home *** CD-ROM | disk | FTP | other *** search
- !JOB NAME=KERMIT
- !PASCAL ME OVER KERMIT_OBJ (NDB,LS)
- {
- Program Kermit implements the KERMIT protocol under HONEYWELL/CP6.
-
- Authors: Philip Murton - original RT-11 pascal program.
- Bruce W. Pinn - modified version for VAX/VMS.
- Douglas Vaughan, Cheryl Poostay, Kevin Asplen, Jay Undercoffler
- - modified VAX/VMS version for HONEYWELL/CP6.
-
- Date: March 27, 1985
-
- Site: Bucknell University Computing Services
- Lewisburg, Pennsylvania 17837
- (717) 524-1801
- }
- program Kermit(input,output,LINE,ERRORS,DiskOutFile,DiskInFile);
-
- label
- 9999; { used only to simulate a "halt" instruction }
-
- {%INCLUDE 'CURRENT_GLOBAL'(lines 22-102)}
- {label
- 9999; } { used only to simulate a "halt" instruction }
-
- const
-
-
- { other io-related stuff }
- IOERROR = 0; { status values for open files }
- IOAVAIL = 1;
- IOREAD = 2;
- IOWRITE = 3;
-
-
- { universal manifest constants }
- NULL = 0;
- ENDSTR = -1 ; { null-terminated strings }
- ENDFILE = -2 ;
- ENDOFQIO = -3 ;
- MAXSTR = 100; { longest possible string }
- CONLENGTH = 20;
-
- { ascii character set in decimal }
- BACKSPACE = 8;
- TAB = 9;
- NEWLINE = 10;
- BLANK = 32;
- EXMARK = 33;
- SHARP = 35;
- AMPERSAND = 38;
- PERIOD = 46;
- RABRACK = 62;
- QUESTION = 63;
- GRAVE = 96;
- TILDE = 126;
- LETA = 65;
- LETZ = 90;
- LETsa = 97;
- LETsz = 122;
- LET0 = 48;
- LET9 = 57;
-
- SOH = 1; { ascii SOH character }
- CR = 13; { CR }
- DEL = 127; { rubout }
-
- DEFTRY = 5; { default for number of retries }
- DEFITRY = 10; { default for number of retries on init }
- DEFTIMEOUT = 20; { default time out }
- DEFDELAY = 10 ; { delay before sending first init }
- NUMPARAM = 7; { number of parameters in init packet }
- DEFQUOTE = SHARP; { default quote character }
- DEFEBQUOTE = AMPERSAND;
- DEFPAD = 0; { default number of padding chars }
- DEFPADCHAR = 0; { default padding character }
-
- { SYSTEM DEPENDENT }
- DEFEOL = CR;
-
- { packet TYPES }
-
- TYPEB = 66; { ord('B') }
- TYPED = 68; { ord('D') }
- TYPEE = 69; { ord('E') }
- TYPEF = 70; { ord('F') }
- TYPEN = 78; { ord('N') }
- TYPES = 83; { ord('S') }
- TYPET = 84; { ord('T') }
- TYPEY = 89; { ord('Y') }
- TYPEZ = 90; { ord('Z') }
-
- MAXCMD = 10;
-
-
- LineInSize = 512;
-
- { Command parser constants }
- SMALLSIZE = 13;
- LARGESIZE = 80;
- MINPACKETSIZE = 10;
- MAXPACKETSIZE = 94;
-
- { %include 'CURRENT_CONSTANT' (lines 105-395)}
- NULLTOKE = 100;
- RANGENULL = 101;
- KERMITPROMPT = 'Kermit-CP6>';
- KERMITHELP = 'KERMITHLP:';
-
- INVALIDCOMMAND = 1;
- INVALIDSETCOMMAND = 2;
- INVALIDSHOWCOMMAND = 3;
- NOTIMPLEMENTED = 4;
- INVALIDFILESPEC = 5;
- INVALIDSETCVALUE = 6;
- INVALIDSETDVALUE = 7;
- INVALIDSETOVALUE = 8;
- INVALIDSETRANGE = 9;
- SENDPARMS = 10;
- RECEIVEPARMS = 11;
- LOCALPARMS = 12;
- BLANKLINE = 13;
- NOHELPAVAILABLE = 14;
- IBEXSPAWNFAILED = 15;
-
- cSET = 'SET ';
- cSHOW = 'SHOW ';
- cSTATUS = 'STATUS ';
- cCONNECT = 'CONNECT ';
- cHELP = 'HELP ';
- cEXIT = 'EXIT ';
- cQUIT = 'QUIT ';
- cQUESTION = '? ';
- cSEND = 'SEND ';
- cRECEIVE = 'RECEIVE ';
- cDEBUGGING = 'DEBUGGING ';
- cLOCALECHO = 'LOCAL-ECHO ';
- cDELAY = 'DELAY ';
- cPACKETLENGTH = 'PACKET-LENGTH';
- cPADDING = 'PADDING ';
- cPADCHAR = 'PADCHAR ';
- cTIMEOUT = 'TIMEOUT ';
- cENDOFLINE = 'END-OF-LINE ';
- cQUOTE = 'QUOTE ';
- cALL = 'ALL ';
- cON = 'ON ';
- cOFF = 'OFF ';
- cBADTOKEN = 'XX ';
- cTRANSMODE = 'TRANSMODE ';
- cASCII = 'ASCII ';
- cBINARY = 'BINARY ';
- cEIGHTQUOTE = 'EIGHT-QUOTE ';
- cFILERECORD = 'FILERECORD ';
- cCR = 'CR ';
- cLF = 'LF ';
- cCRLF = 'CRLF ';
- cPARITY = 'PARITY ';
- cEVEN = 'EVEN ';
- cODD = 'ODD ';
- cNONE = 'NONE ';
- cSPEED = 'SPEED ';
- cIBEX = 'IBEX ';
-
- uSET = 3;
- uMSEND = 3;
- uMRECEIVE = 1;
- uSHOW = 2;
- uSTATUS = 2;
- uCONNECT = 1;
- uIBEX = 1;
- uHELP = 1;
- uQUESTION = 1;
- uEXIT = 1;
- uQUIT = 1;
- uSEND = 1;
- uRECEIVE = 1;
- uDEBUGGING = 3;
- uFILERECORD = 1;
- uTRANSMODE = 1;
- uLOCALECHO = 2;
- uDELAY = 3;
- uPACKETLENGTH = 3;
- uPADDING = 4;
- uPADCHAR = 4;
- uTIMEOUT = 1;
- uENDOFLINE = 1;
- uQUOTE = 1;
- uALL = 1;
- uON = 2;
- uOFF = 2;
- uBADTOKEN = 1;
- uCR = 2;
- uLF = 1;
- uCRLF = 2;
- uPARITY = 1;
- uEVEN = 1;
- uODD = 1;
- uNONE = 1;
- uSPEED = 2;
- uASCII = 1;
- uBINARY = 1;
- uQUOTED = 1;
- uEIGHTQUOTE = 1;
-
- oON = 0;
- oOFF = 1;
- oEVEN = 2;
- oODD = 3;
- oNONE = 4;
- oSET = 5;
- oSHOW = 6;
- oSTATUS = 7;
- oCONNECT = 8;
- oHELP = 9;
- oEXIT = 10;
- oQUIT = 11;
- oSEND = 12;
- oRECEIVE = 13;
- oDEBUGGING = 14;
- oLOCALECHO = 15;
- oDELAY = 16;
- oPACKETLENGTH = 17;
- oPADDING = 18;
- oPADCHAR = 19;
- oTIMEOUT = 20;
- oENDOFLINE = 21;
- oQUOTE = 22;
- oQUESTIONM = 23;
- oALL = 24;
- oBADTOKEN = 25;
- oFILERECORD = 26;
- oCR = 27;
- oLF = 28;
- oCRLF = 29;
- oPARITY = 30;
- oSPEED = 31;
- oIBEX = 32;
- oTRANSMODE = 33;
- oASCII = 34;
- oBINARY = 35;
- oEIGHTQUOTE = 36;
- oXXXX = 100 ;
-
- oMAINTYPE = 1;
- oSETTYPE = 2;
- oSHOWTYPE = 3;
- oSENDTYPE = 4;
- oRECEIVETYPE = 5;
- oDEBUGTYPE = 6;
- oFILERECTYPE = 8;
- oLOCECHOTYPE = 9;
- oPARITYTYPE = 10;
- oTRANSTYPE = 11;
-
- DECIMAL = 0;
- SDECIMAL = 1;
- OCTAL = 2;
- CHRACTER = 3;
- IDECIMAL = 4;
- EBCHRACTER = 5;
-
- oASCSTATE = 1;
- oBINSTATE = 0;
-
- o300BAUD = 300;
- o600BAUD = 600;
- o1200BAUD = 1200;
- o2400BAUD = 2400;
- o4800BAUD = 4800;
- o9600BAUD = 9600;
-
- type
- character = ENDOFQIO..255; { byte-sized. ascii + other stuff }
- schar = -128..127;
- wordInteger = 0..65535;
- string = array [1..MAXSTR] of character;
- vstring = record
- len : integer;
- ch : array [1..MAXSTR] of char;
- end;
- cstring = PACKED array [1..CONLENGTH] of char;
- IOstate = IOERROR..IOWRITE;
- filedesc = (keyboard,screen,RS232,history,outfile,infile) ;
-
- IOBUFFER = packed array[1..LineInSize] of character ;
- { Eight bit file stuff }
- EBQtype = (Ascii, Binary);
-
- SevenEight =
- RECORD
- CASE mode : EBQtype OF
- Ascii : ( seven : CHAR );
- Binary : ( eight : 0..255 )
- END ;
- { Data TYPES for Kermit }
- Packet = RECORD
- mark : character; { SOH character }
- count: character; { # of bytes following this field }
- seq : character; { sequence number modulo 64 }
- ptype: character; { d,y,n,s,b,f,z,e,t packet type }
- data : string; { the actual data }
- end;
- { chksum is last validchar in data array }
- { eol is added, not considered part of packet proper }
-
- Command = (Transmit,Receive,Invalid,Connect);
- KermitStates = (FileData,Init,Break,FileHeader,EOFile,Complete,Abort);
- EOLtype = (LineFeed,CrLf,JustCr);
-
- Stats = integer;
- Ppack = ^Packet;
-
- Intype = (nothing,CRin,abortnow);
-
- { Parser defined types }
- vmsString = packed array [1..255] of char;
- string13 = packed array [1..SMALLSIZE] of char;
- string80 = packed array [1..LARGESIZE] of char;
- NewString80 =
- record
- StringPart : packed array [1..80] of char;
- LengthOfSP : 0..80
- end;
-
- var
- cmdargs : 0..MAXCMD;
- LINE,ERRORS,DiskOutFile,DiskInFile : text;
- file3cnt, file4cnt : integer;
-
- { varibles for Kermit }
- DiskFile : IOstate ; { File being read/written }
- SaveState : kermitstates;
- NextArg : integer; { next argument to process }
- local : boolean; { local/remote flag }
- MaxTry : integer;
- n : integer; { packet number }
- NumTry : integer; { times this packet retried }
- OldTry : integer;
- Delay : integer;
- Pad, MyPad : integer; { number of padding characters I need }
- PadChar, MyPadChar: INTEGER;
- MyTimeOut, TheirTimeOut : integer;
- timeOutStatus : boolean;
- Runtype, oldRunType : command;
- State : kermitstates;
-
- STDERR, LineOUT, ControlIN, ControlOUT : filedesc;
- SizeRecv, SizeSend : integer;
- SendEOL, SendQuote : INTEGER;
- myEOL,myQuote: INTEGER;
- EOLFORFILE : EOLtype;
- NumSendPacks, NumRecvPacks : integer;
- NumACK, NumNAK : integer;
- NumACKrecv, NumNAKrecv, NumBADrecv : integer;
- RunTime : integer;
- ChInFileRecv, ChInPackRecv, ChInFileSend, ChInPackSend : Stats;
- Debug : boolean;
- ThisPacket : Ppack; { current packet being sent }
- LastPacket : Ppack; { last packet sent }
- CurrentPacket : Ppack; { current packet received }
- NextPacket : Ppack; { next packet being received }
- InputPacket : Ppack; { save input to do debug }
-
- { these are used for the Receive Packet procedures }
- FromConsole : Intype ;
- check: integer; { Checksum }
- PacketPtr : integer; { pointer to InputPacket }
- dataptr : integer; { pointer to data of Packet }
- fld : 0..5; { current fld number }
- t : character; { input character }
- finished : boolean; { finished packet ? }
- restart : boolean; { restart packet ? }
- control : boolean; { quoted ? }
- isgood : boolean; { packet is good ? }
-
- IncomingPacket : IOBUFFER;
- BufferPointer, BufferEnd : integer ;
-
- { Eight Bit Quoting Info }
- sentEBQuote, recvdEBQuote, needEBQuote : boolean; { Used for determining 8 bit state }
- EBQState : EBQtype; { ... }
- EBQchar : INTEGER; { Quote character for 8 bit trans }
- ishigh : integer; { Shift to put high bit on }
-
- { Parser defined variables }
- commandLine : string80;
- fileSpec : string80;
- exitProgram : boolean;
- localEcho, sFileSpec, rFileSpec, lSpeed, transtype : integer;
- escape, debugging, commandLen, fileEol, parity : integer;
- width, linespeed : integer ;
- MAXPACK : 0..MAXPACKETSIZE ; {number of characters must be less }
- {than platen width-otherwise LF is inserted}
-
- DEFPARITY : integer ;
-
-
- PROCEDURE Take_Nap (seconds : integer) ; external ;
- PROCEDURE set_profile (mode : integer ; {0=get,1=restore}
- var linespeed : integer ;
- var width : integer ; {max line before wrap-around}
- var parity : integer ) ; external ;
- PROCEDURE set_prompt {NO PROMPT} ; external ;
- PROCEDURE set_parity (parity : integer) ; external ;
- function ReadCommLine (var IncomingPacket : IOBUFFER ;
- N : integer ;
- timeout : integer ;
- var status : boolean ;
- var endofline : integer ;
- var start : integer ) : integer ;
- type line = packed array [1..LineInSize] of char ;
- var Buffer : line ;
- ChValue : SevenEight ;
- k : integer ;
- EOL : char;
- PROCEDURE getlineinput (var Buffer : line ;
- LENGTH : integer ;
- wait : integer ; {timeout seconds}
- var status : boolean ) ; external ;
-
- begin
- EOL := chr (endofline) ;
- for k := 1 to LineInSize do Buffer[k] := EOL ;
- start := 0 ;
- ReadCommLine := 0;
- getlineinput (Buffer, LineInSize, timeout, status) ;
- begin
- k := 1 ;
- while (k <= LineInSize) and (Buffer[k] <> EOL) do
- begin
- ReadCommLine := k ;
- ChValue.seven := Buffer[k] ;
- IncomingPacket[k] := ChValue.eight ;
- k := k + 1
- end ;
- end
- end;
-
-
- function min (a,b: integer) : integer ;
- begin if a <= b then
- min := a
- else
- min := b
- end ;
-
- function max (a,b: integer) : integer ;
- begin if a >= b then
- max := a
- else
- max := b
- end ;
- procedure GetCf(var c:character);
- var
- ch : SevenEight ;
- begin
- if not eof(DiskInFile) then
- if eoln(DiskInFile) then
- begin
- readln(DiskInFile);
- c := NEWLINE
- end
- else
- begin
- read(DiskInFile, ch.seven) ;
- c := ch.eight
- end
- else
- c := ENDFILE
- end;
-
-
-
- procedure DebugMessage(c : cstring);
- forward;
-
-
- procedure PutCln(x:cstring;
- fd:filedesc);
- forward;
-
-
- procedure AddTo(var sum : Stats;
- inc:integer);
- forward;
-
-
- procedure PutCN(x:cstring;
- v : integer;
- fd:filedesc);
- forward;
-
-
- procedure FinishUp(noErrors : boolean);
- forward;
-
-
- procedure ErrorPack(c:cstring);
- forward;
-
-
- procedure ProgramHalt; { used by external procedures for halt }
- begin
- GOTO 9999
- end;
-
- function FileOpen (FileName : string80 ; mode : filedesc) : IOstate ;
- begin
- case mode of
- infile : begin
- Set_File_Parameters (DiskInFile, FileName,
- 'DCB = DISKINFILE, ERROR=CONTINUE') ;
- reset (DiskInFile) ;
- if File_Status (DiskInFile) = 0 then
- FileOpen := IOREAD
- else
- FileOpen := IOERROR
- end ;
-
- outfile : begin
- Set_File_Parameters (DiskOutFile, FileName,
- 'DCB = DISKOUTFILE, CTG = YES') ;
- rewrite (DiskOutFile ) ;
- FileOpen := IOWRITE ;
- end ;
- end {case}
- end;
-
- procedure Sclose (var fd : IOstate);
- begin
- case fd of
- IOREAD: Close_file (DiskInFile) ;
- IOWRITE: Close_file (DiskOutFile)
- end {case};
- fd := IOAVAIL
- end;
-
- procedure Putcf (c : character; fd : filedesc);
- var byte : SevenEight ;
- BEGIN
- CASE FD OF
- screen:
- IF (C=NEWLINE) THEN
- WRITELN(OUTPUT)
- ELSE
- WRITE(OUTPUT,CHR(C));
- history:
- IF (C=NEWLINE) THEN
- WRITELN(ERRORS)
- ELSE
- WRITE(ERRORS,CHR(C));
- RS232: WRITE(LINE,CHR(C));
- outfile:
- IF (C=NEWLINE) THEN
- WRITELN(DiskOutFile)
- ELSE
- begin
- byte.eight := c ;
- WRITE(DiskOutFile, byte.seven)
- end
- END;
- END;
-
- function getc (var c : character) : character;
- { getc (UCB) -- get one character from standard input }
-
- var
- ch : char;
- begin
- if eof then
- c := ENDFILE
- else
- if eoln then
- begin
- readln;
- c := NEWLINE
- end
- else
- begin
- read(ch);
- c := ord(ch)
- end;
- getc := c
- end;
-
-
- procedure Putc (c : character);
- { putc (UCB) -- put one character on standard output }
- begin
- if c = NEWLINE then
- writeln
- else
- write(chr(c));
- end;
-
-
-
-
- procedure PutStr (var s : string; f : filedesc);
- { putstr (UCB) -- put out string on file }
-
- var
- i : integer;
- begin
- i := 1;
- while (s[i] <> ENDSTR) do
- begin
- Putcf(s[i], f);
- i := i + 1
- end
- end;
-
-
- function ItoC (n : integer; var s : string; i : integer)
- : integer; { returns end of s }
- { ItoC - convert integer n to char string in s[i]... }
- begin
- if (n < 0) then
- begin
- s[i] := ord('-');
- ItoC := ItoC(-n, s, i+1)
- end
- else
- begin
- if (n >= 10) then
- i := ItoC(n div 10, s, i);
- s[i] := n mod 10 + ord('0');
- s[i+1] := ENDSTR;
- ItoC := i + 1
- end
- end;
-
-
- function LengthSTIP (var s : string) : integer;
- { lengthSTIP -- compute length of string }
-
- var
- n : integer;
- begin
- n := 1;
- while (s[n] <> ENDSTR) do
- n := n + 1;
- LengthSTIP := n - 1
- end;
-
-
- procedure Scopy (var src : string; i : integer;
- var dest : string; j : integer);
- { scopy -- copy string at src[i] to dest[j] }
- begin
- while (src[i] <> ENDSTR) do
- begin
- dest[j] := src[i];
- i := i + 1;
- j := j + 1
- end;
- dest[j] := ENDSTR
- end;
-
-
- function IsUpper (c : character) : boolean;
- { isupper -- true if c is upper case letter }
- begin
- isupper := (c >= ord('A')) and (c <= ord('Z'))
- end;
-
-
- function IndexSTIP (var s : string; c : character) : integer;
- { IndexSTIP -- find position of character c in string s }
-
- var
- i : integer;
- begin
- i := 1;
- while (s[i] <> c) and (s[i] <> ENDSTR) do
- i := i + 1;
- if (s[i] = ENDSTR) then
- IndexSTIP := 0
- else
- IndexSTIP := i
- end;
-
-
- procedure CtoS(x:cstring; var s:string);
- { convert constant to STIP string }
-
- var
- i : integer;
- begin
- for i:=1 to CONLENGTH do
- s[i] := ord(x[i]);
- s[CONLENGTH+1] := ENDSTR;
- end;
-
-
- procedure PutCon(x:cstring;
- fd:filedesc);
- { output literal }
-
- var
- s: string;
- begin
- CtoS(x,s);
- PutStr(s,fd);
- end;
-
-
- procedure PutCln;
- { output literal followed by NEWLINE }
- begin
- PutCon(x,fd);
- Putcf(NEWLINE,fd);
- end;
-
-
- procedure PutNum(n:integer;
- fd:filedesc);
- { Ouput number }
-
- var
- s: string;
- dummy: integer;
- begin
- s[1] := BLANK;
- dummy := ItoC(n,s,2);
- PutStr(s,fd);
- end;
-
-
- procedure PutCS(x:cstring;
- s : string;
- fd:filedesc);
- { output literal & string }
- begin
- PutCon(x,fd);
- PutStr(s,fd);
- Putcf(NEWLINE,fd);
- end;
-
-
- procedure PutCN;
- { output literal & number }
- begin
- PutCon(x,fd);
- PutNum(v,fd);
- Putcf(NEWLINE,fd);
- end;
-
-
- procedure AddTo;
- begin
- sum := sum + inc;
- end;
-
-
- procedure OverHd(p,f: Stats;
- var o:integer);
- { Calculate OverHead as % }
- { 0verHead := (p-f)*100/f }
- begin
- if (f <> 0) then
- o := ((p - f)*100) div f
- else
- o := 100;
- end;
-
-
- procedure CalRat(f: Stats;
- t:integer;
- var r:integer);
- { Calculate Effective Baud Rate }
- { Rate = f*10/t }
- begin
- if (t <> 0) then
- r := (f * 10) div t
- else
- r := 0;
- end;
-
- procedure DebugMessage;
- { Print writeln if debug }
- begin
- if debug then
- PUTCLN(C,STDERR);
- end;
-
-
- procedure DebugMessNumb(s : cstring; val : integer);
- { Print message and a number }
- begin
- if debug then
- begin
- Putcln(s, STDERR);
- PutNum(val, STDERR);
- end;
- end;
-
-
-
-
- procedure PutPacket(p : Ppack); { Output Packet }
-
- var
- i : integer;
- begin
- DebugMessage('PutPacket... ');
- if (Pad >0) then
- for i := 1 to Pad do
- Putcf(PadChar,LineOut);
- with p^ do
- begin
- Putcf(mark,LineOut);
- Putcf(count,LineOut);
- Putcf(seq,LineOut);
- Putcf(ptype,LineOut);
- PutStr(data,LineOut);
- end;
-
- Putcf(NEWLINE,LineOut) ;
- end;
-
-
- function GetIn : character; { get character }
- { Should return NULL ( ENDSTR ) if no characters }
-
- var
- c : character;
- begin
- BufferPointer := BufferPointer + 1;
-
- if (BufferPointer <= BufferEnd) then
- c := IncomingPacket[BufferPointer]
- else
- c := ENDOFQIO;
- GetIn := c;
- if (c <> NULL) then
- AddTo(ChInPackRecv,1)
- end;
-
-
- function MakeChar(c:character): character;
- { convert integer to printable }
- begin
- MakeChar := c+BLANK;
- end;
-
-
- function UnChar(c:character): character;
- { reverse of makechar }
- begin
- UnChar := c - BLANK
- end;
-
-
- function IsControl(c:character): boolean;
- { true if control }
- begin
- if (c >= NULL) then
- IsControl := (c = DEL ) or (c < BLANK )
- else
- IsControl := IsControl(c + 128);
- end;
-
-
- function Ctl(c:character): character;
- { c XOR 100 }
- begin
- if (c >= NULL) then
- if (c < 64) then
- c := c + 64
- else
- c := c-64
- else
- c := Ctl(c + 128) - 128;
-
- Ctl := c;
- end;
-
-
- function Checkfunction(c:integer): character;
- { calculate checksum }
-
- var
- x: integer;
- begin
- DebugMessage('Checkfunction... ');
- { Checkfunction := (c + ( c and 300 ) /100 ) and 77; }
- x := (c MOD 256 ) DIV 64;
- x := x+c;
- Checkfunction := x MOD 64;
- end;
-
-
- procedure SetEBQuoteState;
- begin
- if (EBQState = Binary) then
- begin
- transType := oBINARY;
- end
- else
- begin
- transType := oASCII;
- end;
- end;
-
-
- procedure EnCodeParm(var data:string); { encode parameters }
-
- var
- i: integer;
- begin
- DebugMessage('EnCodeParm... ');
- for i:=1 to NUMPARAM do
- data[i] := BLANK;
- data[NUMPARAM+1] := ENDSTR;
- data[1] := MakeChar(SizeRecv); { my biggest packet }
- data[2] := MakeChar(MyTimeOut); { when I want timeout}
- data[3] := MakeChar(MyPad); { how much padding }
- data[4] := Ctl(MyPadChar); { my padding character }
- data[5] := MakeChar(myEOL); { my EOL }
- data[6] := MyQuote; { my quote char }
-
- { Handle eight bit quoting parm }
- case RunType of
- Transmit :
- if EBQState = Binary then
- begin
- if EBQChar <> DEFEBQUOTE then
- begin
- data[7] := EBQChar;
- sentEBQuote := true;
- end
- else
- data[7] := TYPEY;
- end
- else
- data[7] := TYPEN;
-
- Receive :
- if EBQState = Binary then
- begin
- if recvdEBQuote then
- data[7] := TYPEY
- else
- if needEBQuote then
- data[7] := EBQChar
- else
- begin
- EBQState := Ascii;
- data[7] := TYPEN;
- end;
- end
- else
- data[7] := TYPEN;
- end;
-
- SetEBQuoteState;
-
- end;
-
-
- function CheckEBQuote(inchr : character;
- var outchr : INTEGER) : EBQtype;
- begin
- if (inchr in [EXMARK..RABRACK, GRAVE..TILDE]) then
- begin
- outchr := inchr;
- CheckEBQuote := Binary
- end
- else
- CheckEBQuote := Ascii;
- end;
-
-
- procedure DeCodeParm(var data:string); { decode parameters }
-
- var
- InEBQChar : character;
- begin
- DebugMessage('DeCodeParm... ');
- SizeSend := UnChar(data[1]);
- TheirTimeOut := UnChar(data[2]); { when I should time out }
- Pad := UnChar(data[3]); { padding characters to send }
- PadChar := Ctl(data[4]); { padding character }
- SendEOL := UnChar(data[5]); { EOL to send }
- SendQuote := data[6]; { quote to send }
-
- { Handle eight bit quoting parm }
- InEBQchar := data[7];
- case RunType of
- Transmit :
- if EBQState = Binary then
- begin
- if sentEBQuote then
- begin
- if InEBQchar <> TYPEY then
- EBQState := Ascii;
- end
- else
- if InEBQchar = TYPEN then
- EBQState := Ascii
- else
- EBQState := CheckEBQuote(InEBQchar, EBQchar);
- end;
-
- Receive :
- if EBQState = Binary then
- begin
- if InEBQchar = TYPEY then
- needEBQuote := true
- else
- if InEBQchar = TYPEN then
- EBQState := Ascii
- else
- begin
- EBQState := CheckEBQuote(InEBQchar, EBQchar);
- if EBQState = Binary then
- recvdEBQuote := true;
- end;
- end;
- end;
-
- SetEBQuoteState;
-
- end;
-
-
- procedure StartRun; { initialization as necessary }
- begin
- DebugMessage('StartRun... ');
-
- NumSendPacks := 0;
- NumRecvPacks := 0;
- NumACK := 0;
- NumNAK := 0;
- NumACKrecv := 0;
- NumNAKrecv := 0;
- NumBADrecv := 0;
-
- ChInFileRecv := 0;
- ChInFileSend := 0;
- ChInPackRecv := 0;
- ChInPackSend := 0;
-
-
- State := Init; { send initiate is the start state }
- NumTry := 0; { say no tries yet }
- end;
-
-
- procedure ResetKermitPacketNumber;
- begin
- n := 0;
- end;
-
-
- procedure KermitInit; { initialize various parameters & defaults }
- VAR platen : integer ;
- begin
- set_prompt ;
-
- set_file_parameters (line,' ','ORG = TERMINAL') ;
- set_profile (0, {save terminal characteristics}
- linespeed, {connect baud rate}
- platen, {total packet most be smaller than this}
- DEFPARITY) ; {connect parity}
- case linespeed of
- 0,1,3,8,10,11 : {not support by CP_6} lSpeed := 0 ;
- 2,4,5,6 : lSpeed := o300BAUD ;
- 7 : lSpeed := o600BAUD ;
- 9 : lSpeed := o1200BAUD ;
- 12 : lSpeed := o2400BAUD ;
- 13 : lSpeed := o4800BAUD ;
- 14,15 : lSpeed := o9600BAUD ;
- end {case} ;
- MAXPACK := MAXPACKETSIZE ;
- REWRITE(LINE);
- REWRITE(ERRORS);
-
- Pad := DEFPAD; { set defaults }
- MyPad := DEFPAD;
- PadChar := DEFPADCHAR;
- MyPadChar := DEFPADCHAR;
- TheirTimeOut := DEFTIMEOUT;
- MyTimeOut := DEFTIMEOUT;
- Delay := DEFDELAY;
- SizeRecv := MAXPACKETSIZE ;
- SizeSend := MAXPACK;
- SendEOL := DEFEOL;
- MyEOL := DEFEOL;
- SendQuote := DEFQUOTE;
- MyQuote := DEFQUOTE;
- EBQChar := DEFEBQUOTE;
- MaxTry := DEFITRY;
-
- localEcho := oOFF;
- parity := DEFPARITY ;
- fileEol := oCRLF;
- transtype := oASCII;
- Local := true ; { default to local }
-
- Debug := false;
- debugging := oOFF;
- Runtype := invalid;
-
- DiskFile := IOERROR; { to indicate not open yet }
- STDERR := history ;
- LineOUT := RS232 ;
- ControlIN := keyboard ;
- ControlOUT := screen ;
-
- new(ThisPacket);
- new(LastPacket);
- new(CurrentPacket);
- new(NextPacket);
- new(InputPacket);
-
- NumSendPacks := 0;
- NumRecvPacks := 0;
- NumACK := 0;
- NumNAK := 0;
- NumACKrecv := 0;
- NumNAKrecv := 0;
- NumBADrecv := 0;
-
- ChInFileRecv := 0;
- ChInFileSend := 0;
- ChInPackRecv := 0;
- ChInPackSend := 0;
-
-
- NumTry := 0; { say no tries yet }
- OldRunType := connect ;
- EBQState := Ascii ;
- end;
-
-
- procedure FinishUp;
- { do any end of transmission clean up }
- begin
- DebugMessage('FinishUp... ');
-
- {Sclose(DiskFile);}
-
- if not(noErrors) then
- else
- begin
- ErrorPack('Aborting Transfer ');
- end;
-
- oldRunType := RunType;
- PutCf(NEWLINE, ControlOUT);
-
- end;
-
-
- procedure DebugPacket(mes : cstring;
- var p : Ppack);
- { Print Debugging Info }
- begin
- DebugMessage('DebugPacket... ');
- PutCon(mes,STDERR);
- with p^ do
- begin
- PutNum(Unchar(count),STDERR);
- PutNum(Unchar(seq),STDERR);
- Putcf(BLANK,STDERR);
- Putcf(ptype,STDERR);
- Putcf(NEWLINE,STDERR);
- PutStr(data,STDERR);
- Putcf(NEWLINE,STDERR);
- end;
- end;
-
-
- procedure ReSendPacket;
- { re -sends previous packet }
- begin
- DebugMessage('ReSendPacket... ');
- NumSendPacks := NumSendPacks+1;
- if Debug then
- DebugPacket('Re-Sending ... ',LastPacket);
- PutPacket(LastPacket);
- end;
-
-
- procedure SendPacket;
- { expects count as length of data portion }
- { and seq as number of packet }
- { builds & sends packet }
-
- var
- i,len,chksum : integer;
- temp : Ppack;
- begin
- DebugMessage('Sending Packet ');
- if (NumTry <> 1) and (Runtype = Transmit ) then
- ReSendPacket
- else
- begin
- with ThisPacket^ do
- begin
- mark := SOH; { mark }
- len := count; { save length }
- count := MakeChar(len+3); { count = 3+length of data }
- seq := MakeChar(seq); { seq number }
- chksum := count + seq + ptype;
- if ( len > 0) then { is there data ? }
- for i:= 1 to len do
- if (data[i] >= 0) then
- chksum := chksum + data[i] { loop for data }
- else
- chksum := chksum + data[i] + 256;
- chksum := Checkfunction(chksum); { calculate checksum }
- data[len+1] := MakeChar(chksum); { make printable & output }
- data[len+2] := SendEOL; { EOL }
- data[len+3] := ENDSTR;
- end;
-
- NumSendPacks := NumSendPacks+1;
- if Debug then
- DebugPacket('Sending ... ',ThisPacket);
- PutPacket(ThisPacket);
-
- if Runtype = Transmit then
- begin
- temp := LastPacket;
- LastPacket := ThisPacket;
- ThisPacket := temp;
- end;
- end;
- end;
-
-
- procedure SendACK(n:integer); { send ACK packet }
- begin
- DebugMessage('SendAck... ');
- with ThisPacket^ do
- begin
- count := 0;
- seq := n;
- ptype := TYPEY;
- end;
- SendPacket;
- NumACK := NumACK+1;
- end;
-
- procedure SendNAK(n:integer); { send NAK packet }
- begin
- DebugMessage('SendNAK... ');
- with ThisPacket^ do
- begin
- count := 0;
- seq := n;
- ptype := TYPEN;
- end;
- SendPacket;
- NumNAK := NumNAK+1;
- end;
-
-
- procedure ErrorPack;
- { output Error packet if necessary -- then exit }
- begin
- DebugMessage('ErrorPack... ');
- with ThisPacket^ do
- begin
- seq := n;
- ptype := TYPEE;
- CtoS(c,data);
- count := LengthSTIP(data);
- end;
- SendPacket;
- end;
-
-
- procedure PutErr(c:cstring);
- { Print error_messages }
- begin
- DebugMessage('PutErr... ');
- if debug then
- Putcln(c,STDERR);
- end;
-
-
- procedure Field1; { Count }
-
- var
- test: boolean;
- begin
- DebugMessage('Field1... ');
- with NextPacket^ do
- begin
- InputPacket^.count := t;
- count := UnChar(t);
- test := (count >= 3) or (count <= SizeRecv-2);
- if not test then
- DebugMessage('Bad count ');
- isgood := isgood and test;
- end;
- end;
-
-
- procedure Field2; { Packet Number }
-
- var
- test : boolean;
- begin
- DebugMessage('Field2... ');
- with NextPacket^ do
- begin
- InputPacket^.seq := t;
- seq := UnChar(t);
- test := (seq >= 0) or (seq <= 63);
- if not test then
- DebugMessage('Bad seq number ');
- isgood := isgood and test;
- end;
- end;
-
-
- procedure Field3; { Packet type }
-
- var
- test : boolean;
- begin
- DebugMessage('Field3... ');
- with NextPacket^ do
- begin
- ptype := t;
- InputPacket^.ptype := t;
-
- test := (t =TYPEB) or (t=TYPED) or (t=TYPEE) or (t=TYPEF)
- or (t=TYPEN) or (t=TYPES) or (t=TYPEY) or (t=TYPEZ);
- if not test then
- DebugMessage('Bad Packet type ');
- isgood := isgood and test;
- end;
- end;
-
-
- procedure ProcessQuoted; { for data }
- begin
- with NextPacket^ do
- begin
- if (t = MyQuote) or ((t = EBQchar) and (EBQState = Binary)) then
- begin
- if control then
- begin
- data[dataptr] := t + ishigh;
- dataptr := dataptr + 1;
- control := false;
- ishigh := 0;
- end
- else
- if (t = MyQuote) then { Set Control on }
- control := true;
- end
- else
- if control then
- begin
- data[dataptr] := ctl(t) + ishigh;
- dataptr := dataptr + 1;
- control := false;
- ishigh := 0;
- end
- else
- begin
- data[dataptr] := t + ishigh;
- dataptr := dataptr + 1;
- ishigh := 0;
- end;
- end;
- end;
-
-
- procedure Field4; { Data }
- begin
- PacketPtr := PacketPtr+1;
- InputPacket^.data[PacketPtr] := t;
- with NextPacket^ do
- begin
- if ((pType = TYPES) or (pType = TYPEY)) then
- begin
- data[dataptr] := t;
- dataptr := dataptr+1;
- end
- else
- begin
- if (EBQstate = Binary) then
- begin { Has it been quoted }
- if (not(control) and (t = EBQchar)) then
- ishigh := 128
- else
- ProcessQuoted;
- end
- else
- ProcessQuoted;
- end;
- end;
- end;
-
-
- procedure Field5; { Check Sum }
-
- var
- test : boolean;
- begin
- DebugMessage('Field5... ');
- with InputPacket^ do
- begin
- PacketPtr := PacketPtr +1;
- data[PacketPtr] := t;
- PacketPtr := PacketPtr +1;
- data[PacketPtr] := ENDSTR;
- end;
- { end of input string }
- check := Checkfunction(check);
- check := MakeChar(check);
- test := (t=check);
- if not test then
- DebugMessNumb('Bad CheckSum= ', check);
- isgood := isgood and test;
- NextPacket^.data[dataptr] := ENDSTR;
- { end of data string }
- finished := true; { set finished }
- end;
-
-
- procedure BuildPacket;
- { receive packet & validate checksum }
-
- var
- temp : Ppack;
- begin
- with NextPacket^ do
- begin
- if restart then
- begin
- { read until get SOH marker }
- if (t = SOH) then
- begin
- finished := false; { set varibles }
- control := false;
- ishigh := 0; { no shift }
- isgood := true;
- seq := -1; { set return values to bad packet }
- ptype := QUESTION;
- data[1] := ENDSTR;
- data[MAXSTR] := ENDSTR;
- restart := false;
- fld := 0;
- dataptr := 1;
- PacketPtr := 0;
- check := 0;
- end;
- end
- else { have started packet }
- begin
- if (t=SOH) then
- restart := true
- else
- if (t=myEOL) then
- begin
- finished := true;
- isgood := false;
- end
- else
- begin
- case fld of
- { increment field number }
- 0: fld := 1;
- 1: fld := 2;
- 2: fld := 3;
- 3:
- if (count=3) then
- fld := 5
- else
- fld := 4;
- 4:
- if (PacketPtr>=count-3) then
- fld := 5;
- end { case };
-
- if (fld<>5) then
- { add into checksum }
- check := check+t;
-
- case fld of
- 1: Field1;
- 2: Field2;
- 3: Field3;
- 4: Field4;
- 5: Field5;
- end; { case }
- end;
- end;
-
- if finished then
- begin
- if (ptype=TYPEE) and isgood then { error_packets }
- begin
- if Local then
- PutStr(data,STDERR);
- Putcf(NEWLINE,STDERR);
- FinishUp(false);
- ProgramHalt;
- end;
- NumRecvPacks := NumRecvPacks+1;
- if Debug then
- begin
- DebugPacket('Received ... ',InputPacket);
- if isgood then
- PutCln('Is Good ',STDERR);
- end;
- temp := CurrentPacket;
- CurrentPacket := NextPacket;
- NextPacket := temp;
- end;
- end;
- end;
-
-
- function ReceivePacket: boolean;
- begin
- DebugMessage('ReceivePacket... ');
- finished := false;
- restart := true;
- FromConsole := nothing; { No Interupt }
-
- { Obtain packet from VMS incoming channel }
- BufferEnd :=
- ReadCommLine(IncomingPacket,LineInSize,theirtimeout,timeoutstatus,
- MYEOL,BufferPointer) ;
-
- { Check local terminal for abort, resend character }
- if local then
- begin
- {CheckTypeAhead(FromConsole);}
- FROMCONSOLE := NOTHING;
- case FromConsole of
- abortnow:
- begin
- FinishUp(true);
- ProgramHalt;
- end;
- nothing: { nothing };
- CRin:
- begin
- t := MyEOL;
- FromConsole := nothing;
- end;
- end;
- end;
-
- if (BufferEnd = 0) then
- begin
- ReceivePacket := false;
- if (timeOutStatus) then
- begin
- CurrentPacket^.ptype := TYPET;
- restart := true;
- if (debug) then
- PutCln('Timed Out ', STDERR)
- end;
- end
- else
- begin
- repeat
- t := GetIn;
-
- if (t<>ENDOFQIO) then
- BuildPacket
- else
- begin
- finished := true;
- isgood := false;
- end;
- until finished;
-
- ReceivePacket := isgood;
- end;
- end;
-
-
- function ReceiveACK : boolean;
- { receive ACK with correct number }
-
- var
- Ok: boolean;
- begin
- DebugMessage('ReceiveACK... ');
- Ok := ReceivePacket;
- with CurrentPacket^ do
- begin
- if (ptype=TYPEY) then
- NumACKrecv := NumACKrecv+1
- else
- if (ptype=TYPEN) then
- NumNAKrecv := NumNAKrecv+1
- else
- NumBadrecv := NumBadrecv +1;
- { got right one ? }
- ReceiveACK := ( Ok and (ptype=TYPEY) and (n=seq))
- end;
- end;
-
-
- procedure GetData(var newstate:KermitStates);
- { get data from file into ThisPacket }
-
- var
- { and return next state - data & EOF }
- x,c : character;
- i: integer;
- begin
- DebugMessage('GetData... ');
- if (NumTry=1) then
- begin
- i := 1;
- x := ENDSTR;
- with ThisPacket^ do
- begin
- while (i< SizeSend - 8 ) and (x <> ENDFILE) do
- { leave room for quote & NEWLINE }
- begin
- GetCf (x) ;
- if (x<>ENDFILE) then
- begin
- if (x < NULL) then
- case EBQstate of
- ascii :
- ErrorPack('No Binary Support ');
- binary :
- begin
- data[i] := EBQchar;
- i := i + 1;
- x := x + 128;
- end;
- end;
-
- if (IsControl(x)) or (x=SendQuote) or
- ((x = EBQchar) and (EBQState = Binary)) then
- begin { control char -- quote }
- if ((x=NEWLINE) and
- (EBQState <> Binary)) then
- case EOLFORFILE of
- LineFeed: { ok as is };
- CrLf:
- begin
- data[i] := SendQuote;
- i := i+1;
- data[i] := Ctl(CR);
- i := i+1;
- { LF will sent below }
- end;
- JustCR:
- x := CR;
- end { case };
- data[i] := SendQuote;
- i := i+1;
- if (x<>SendQuote) or (x <> EBQchar) then
- data[i] := Ctl(x)
- else
- data[i] := x;
- end
- else { regular char }
- data[i] := x;
- end;
-
- if (x<>ENDFILE) then
- begin
- i := i+1; { increase count for next char }
- AddTo(ChInFileSend,1);
- end;
- end;
-
- data[i] := ENDSTR; { to terminate string }
-
- count := i -1; { length }
- seq := n;
- ptype := TYPED;
-
- if (x=ENDFILE) then
- begin
- newstate := EOFile;
- {Sclose(DiskFile);}
- end
- else
- newstate := FileData;
- SaveState := newstate; { save state }
- end
- end
- else
- newstate := SaveState; { get old state }
- end;
-
-
-
- function GetNextFile: boolean;
- { get next file to send in ThisPacket }
- {there ain't no next file, this baby only sends one file at a time}
- { returns true if no more }
-
- var
- k : integer ;
- result: boolean;
- begin
- DebugMessage('GetNextFile... ');
- result := true;
- if (NumTry=1) then
- begin
- if FileSpec[1] <> ' ' then
- DiskFile := fileopen (filespec,infile) ;
- with ThisPacket^ do
- if DiskFile = IOREAD then
- begin
- k := 1;
- while (FileSpec[k] <> ' ') and (FileSpec[k] <> '.') do
- begin
- data[k] := ord (FileSpec[k]) ;
- FileSpec[k] := ' ';
- data[k+1] := ENDSTR ;
- k := k + 1
- end ;
- count := LengthSTIP(data);
- AddTo(ChInFileSend , count);
- seq := n;
- ptype := TYPEF;
- result := false;
- end ;
-
-
- end ;
- GetNextFile := result;
- end;
- procedure SendFile; { send file name packet }
- begin
- DebugMessage('SendFile... ');
- if NumTry > MaxTry then
- begin
- PutErr ('Send file - Too Many');
- State := Abort; { too many tries, abort }
- end
- else
- begin
- NumTry := NumTry+1;
- if GetNextFile then
- begin
- State := Break;
- NumTry := 0;
- end
- else
- begin
- if debug then
- begin
- if (NumTry = 1) then
- PutStr(ThisPacket^.data,STDERR)
- else
- PutStr(LastPacket^.data,STDERR);
- Putcf(NEWLINE,STDERR);
- end;
- SendPacket; { send this packet }
- if ReceiveACK then
- begin
- State := FileData;
- NumTry := 0;
- n := (n+1) MOD 64;
- end
- end;
- end;
- end;
-
-
- procedure SendData; { send file data packets }
-
- var
- newstate: KermitStates;
- begin
- DebugMessage('SendData... ');
- if debug then
- PutCN ('Sending data ',n,STDERR);
- if NumTry > MaxTry then
- begin
- State := Abort; { too many tries, abort }
- PutErr ('Send data - Too many');
- end
- else
- begin
- NumTry := NumTry+1;
- GetData(newstate);
- SendPacket;
- if ReceiveACK then
- begin
- State := newstate;
- NumTry := 0;
- n := (n+1) MOD 64;
- end
- end;
- end;
-
-
- procedure SendEOF; { send EOF packet }
- begin
- DebugMessage('SendEOF... ');
- if NumTry > MaxTry then
- begin
- State := Abort; { too many tries, abort }
- PutErr('Send EOF - Too Many ');
- end
- else
- begin
- NumTry := NumTry+1;
- if (NumTry = 1) then
- begin
- with ThisPacket^ do
- begin
- ptype := TYPEZ;
- seq := n;
- count := 0;
- end;
- Sclose(DiskFile);
- end;
- SendPacket;
- if ReceiveACK then
- begin
- State := FileHeader;
- NumTry := 0;
- n := (n+1) MOD 64;
- end
- end;
- end;
-
-
- procedure SendBreak; { send break packet }
- begin
- DebugMessage ('Sending break ');
- if NumTry > MaxTry then
- begin
- State := Abort; { too many tries, abort }
- PutErr('Send break -Too Many');
- end
- else
- begin
- NumTry := NumTry+1;
- { make up packet }
- if NumTry = 1 then
- begin
- with ThisPacket^ do
- begin
- ptype := TYPEB;
- seq := n;
- count := 0;
- end
- end;
- SendPacket; { send this packet }
- if ReceiveACK then
- State := Complete;
- end;
- end;
-
-
- procedure SendInit; { send init packet }
- begin
- DebugMessage ('Sending init ');
- if NumTry > MaxTry then
- begin
- State := Abort; { too many tries, abort }
- PutErr('Cannot Initialize ');
- end
- else
- begin
- NumTry := NumTry+1;
- if (NumTry = 1) then
- begin
- with ThisPacket^ do
- begin
- EnCodeParm(data);
- count := NUMPARAM;
- seq := n;
- ptype := TYPES;
- end
- end;
-
- SendPacket; { send this packet }
- if ReceiveACK then
- begin
- with CurrentPacket^ do
- begin
- SizeSend := UnChar(data[1]);
- TheirTimeOut := UnChar(data[2]);
- Pad := UnChar(data[3]);
- PadChar := Ctl(data[4]);
- SendEOL := CR; { default to CR }
- if (LengthSTIP(data) >= 5) then
- if (data[5] <> 0) then
- SendEOL := UnChar(data[5]);
- SendQuote := SHARP; { default # }
- if (LengthSTIP(data) >= 6) then
- if (data[6] <> 0) then
- SendQuote := data[6];
- end;
-
- State := FileHeader;
- NumTry := 0;
- MaxTry := DEFTRY; { use regular default now }
- n := (n+1) MOD 64;
- end;
- end;
- end;
-
-
- procedure SendSwitch;
- { Send-switch is the state table switcher for sending files.
- * It loops until either it is finished or a fault is encountered.
- * Routines called by sendswitch are responsible for changing the state. }
-
- begin
- DebugMessage ('Send Switch ');
- StartRun;
- repeat
- case State of
- FileData: SendData; { data-send state }
- FileHeader: SENDFILE; { send file name }
- EOFile: SendEOF; { send end-of-file }
- Init: begin Take_Nap (Delay); SendInit end ; { send initialize }
- Break: SendBreak; { send break }
- Complete: { nothing };
- Abort: { nothing };
- end { case };
- until ( (State = Abort) or (State=Complete) );
- end;
-
-
- procedure GetFile(data:string);
- { create file from fileheader packet }
-
- const UNDERSCORE = '_' ;
-
- var
- i, j : integer;
- FileName : string80 ;
- begin
- DebugMessage ('GetFile... ');
- with CurrentPacket^ do
- begin
- FileName[1] := '*' ;
- for i := 2 to LARGESIZE do FileName[i] := ' ' ;
- i := 1;
- j := 1;
- repeat
- if (data[i] in [LETA..LETZ, LETsa..LETsz,
- LET0..LET9, PERIOD]) then
- begin
- FileName[j] := chr (data[i]) ;
- if data[i] = PERIOD then
- FileName[j] := UNDERSCORE ;
- j := j + 1 ; if j > LARGESIZE then j := LARGESIZE ;
- end;
- i := i + 1
- until (data[i] = ENDSTR) ;
- end;
- if rFileSpec = oON then
- begin
- rFileSpec := oOFF ;
- FileName := filespec
- end ;
- diskfile := fileopen (FileName, outfile)
- end;
-
-
- procedure ReceiveInit;
- { receive init packet }
- { respond with ACK and our parameters }
-
- var
- receiveStat : boolean;
- begin
- DebugMessage ('ReceiveInit... ');
- if NumTry > MaxTry then
- begin
- State := Abort;
- PutErr('Cannot receive init ');
- end
- else
- begin
- NumTry := NumTry+1;
- receiveStat := ReceivePacket;
- if (ReceiveStat and (CurrentPacket^.ptype = TYPES)) then
- begin
- n := CurrentPacket^.seq;
- DeCodeParm(InputPacket^.data);
- { now send mine }
- with ThisPacket^ do
- begin
- count := NUMPARAM;
- seq := n;
- Ptype := TYPEY;
- EnCodeParm(data);
- end;
- SendPacket;
-
- NumACK := NumACK+1;
- State := FileHeader;
- OldTry := NumTry;
- NumTry := 0;
- MaxTry := DEFTRY; { use regular default now }
- n := (n+1) MOD 64
- end
- else
- begin
- if Debug then
- PutCln('Received Bad init ',STDERR);
- SendNAK(n);
- end;
- end;
- end;
-
-
- procedure DataToFile; { output to file }
-
- var
- len,i : integer;
- temp : string;
- begin
- DebugMessage ('DataToFile... ');
- with CurrentPacket^ do
- begin
- len := LengthSTIP(data);
- AddTo(ChInFileRecv ,len);
- if (EBQState <> Binary) then
- case EOLFORFILE of
- LineFeed:
- PutStr(data,outfile);
- CrLf:
- begin { don't output CR }
- for i:=1 to len do
- if data[i] <> CR then
- Putcf(data[i],outfile);
- end;
- JustCR:
- begin { change CR to NEWLINE }
- for i:=1 to len do
- if data[i]=CR then
- data[i] := NEWLINE;
- PutStr(data,outfile);
- end;
- end
- else
- PutStr(data, outfile);
- end;
- end;
-
-
- procedure dodata; { Process Data packet }
- begin
- DebugMessage ('DoData... ');
- with CurrentPacket^ do
- begin
- if seq = ((n + 63) MOD 64) then
- begin { data last one }
- if OldTry>MaxTry then
- begin
- State := Abort;
- PutErr('Old data - Too many ');
- end
- else
- begin
- SendACK(seq);
- NumTry := 0;
- end;
- end
- else
- begin { data - this one }
- if (n<>seq) then
- SendNAK(n)
- else
- begin
- DataToFile;
- SendACK(n); { ACK }
- OldTry := NumTry;
- NumTry := 0;
- n := (n+1) MOD 64;
- end;
- end;
- end;
- end;
-
- procedure doFileLast; { Process File Packet }
- begin { File header - last one }
- DebugMessage ('DoFileLast... ');
- if OldTry > MaxTry { tries ? } then
- begin
- State := Abort;
- PutErr('Old file - Too many ');
- end
- else
- begin
- OldTry := OldTry+1;
- with CurrentPacket^ do
- begin
- if seq = ((n + 63) MOD 64) then
- { packet number }
- begin { send ACK }
- SendACK(seq);
- NumTry := 0
- end
- else
- begin
- SendNAK(n); { NAK }
- end;
- end;
- end;
- end;
-
-
- procedure DoEOF; { Process EOF packet }
- begin { EOF - this one }
- DebugMessage ('DoEOF... ');
- if CurrentPacket^.seq<>n then { packet number ? }
- SendNAK(n) { NAK }
- else
- begin { send ACK }
- Sclose(DiskFile); { close file }
- SendACK(n);
- OldTry := NumTry;
- NumTry := 0;
- n := (n+1) MOD 64; { next packet }
- State := FileHeader; { change state }
- end;
- end;
-
-
- procedure ReceiveData; { Receive data packets }
-
- var
- strend: integer;
- good : boolean;
-
- begin
- DebugMessage ('ReceiveData... ');
- if NumTry > MaxTry then { check number of tries }
- begin
- State := Abort;
- if debug then
- PutCN('Recv data -Too many ',n,STDERR);
- end
- else
- begin
- NumTry := NumTry+1; { increase number of tries }
- good := ReceivePacket; { get packet }
- with CurrentPacket^ do
- begin
- if debug then
- PutCN('Receiving (Data) ',CurrentPacket^.seq,STDERR);
- if ((ptype = TYPED) or (ptype=TYPEZ)
- or (ptype=TYPEF)) and good then { check type }
- case ptype of
- TYPED: doData;
- TYPEF: doFileLast;
- TYPEZ: doEOF;
- end { case }
- else
- begin
- if Debug then
- PutCln('Expected data pack ',STDERR);
- SendNAK(n);
- end;
- end;
- end;
- end;
-
-
- procedure doBreak; { Process Break packet }
- begin { Break transmission }
- DebugMessage ('DoBreak... ');
- if CurrentPacket^.seq<>n then { packet number ? }
- SendNAK(n) { NAK }
- else
- begin { send ACK }
- SendACK(n) ;
- State := Complete { change state }
- end;
- end;
-
-
- procedure DoFile; { Process file packet }
- begin { File Header }
- DebugMessage ('DoFile... ');
- with CurrentPacket^ do
- begin
- if seq<>n then { packet number ? }
- SendNAK(n) { NAK }
- else
- begin { send ACK }
- AddTo(ChInFileRecv, LengthSTIP(data));
- GetFile(data); { get file name }
- SendACK(n);
- OldTry := NumTry;
- NumTry := 0;
- n := (n+1) MOD 64; { next packet }
- State := FileData; { change state }
- end;
- end;
- end;
-
-
- procedure DoEOFLast; { Process EOF Packet }
- begin { end of File Last One}
- DebugMessage ('DoEOFLast... ');
- if OldTry > MaxTry then
- begin
- State := Abort;
- PutErr('Old EOF - Too many ');
- end
- else
- begin
- OldTry := OldTry+1;
- with CurrentPacket^ do
- begin
- if seq =((n + 63 ) MOD 64) then
- { packet number }
- begin { send ACK }
- SendACK(seq);
- Numtry := 0
- end
- else
- begin
- SendNAK(n); { NAK }
- end
- end;
- end;
- end;
-
-
- procedure DoInitLast;
- begin { Init Packet - last one }
- DebugMessage ('DoInitLast... ');
- if OldTry>MaxTry then
- begin
- State := Abort;
- PutErr('Old init - Too many ');
- end
- else
- begin
- OldTry := OldTry+1;
- if CurrentPacket^.seq = ((n + 63) MOD 64) then
- { packet number }
- begin { send ACK }
- with ThisPacket^ do
- begin
- count := NUMPARAM;
- seq := CurrentPacket^.seq;
- ptype := TYPEY;
- EnCodeParm(data);
- end;
- SendPacket;
- NumACK := NumACK+1;
- NumTry := 0;
- end
- else
- begin
- SendNAK(n); { NAK }
- end;
- end;
- end;
-
-
- procedure ReceiveFile; { receive file packet }
-
- var
- good: boolean;
-
- begin
- DebugMessage ('ReceiveFile... ');
- if NumTry > MaxTry then { check number of tries }
- begin
- State := Abort;
- PutErr('Recv file - Too many');
- end
- else
- begin
- NumTry := NumTry+1; { increase number of tries }
- good := ReceivePacket; { get packet }
- with CurrentPacket^ do
- begin
- if debug then
- PutCN('Receiving (File) ',seq,STDERR);
- if ((ptype = TYPES) or (ptype=TYPEZ)
- or (ptype=TYPEF) or (ptype=TYPEB)) { check type }
- and good then
- case ptype of
- TYPES: doInitLast;
- TYPEZ: doEOFLast;
- TYPEF: doFile;
- TYPEB: doBreak;
- end { case }
- else
- begin
- if Debug then
- PutCln('Expected File Pack ',STDERR);
- SendNAK(n);
- end;
- end;
- end;
- end;
-
-
- procedure RecvSwitch; { this procedure is the main receive routine }
- begin
- DebugMessage ('RecvSwitch... ');
- StartRun;
- repeat
- case State of
- FileData: ReceiveData;
- Init: ReceiveInit;
- Break: { nothing };
- FileHeader: ReceiveFile;
- EOFile: { nothing };
- Complete: { nothing };
- Abort: { nothing };
- end;
- { case }
- until (State = Abort ) or ( State = Complete );
- end;
-
-
- procedure KermitMain; { Main procedure }
-
- var
- aline : string;
- j : integer;
- errorOccurred : boolean;
- begin
-
- DebugMessage ('KermitMain... ');
-
- errorOccurred := false;
- case Runtype of
- Receive:
- begin { filename is optional here }
- RecvSwitch;
- end;
- Transmit:
- SendSwitch;
-
- Invalid: { nothing };
- end; { case }
-
- FinishUp(errorOccurred); { end of program }
-
- end { main };
-
- { Include the parser into kermit.(lines 2355-4263) }
- { Determine length of string. }
-
- function LenString(var tempStr : string80) : integer;
-
- var
- i : integer;
- endofstring : boolean;
- begin
- i := 80;
- endofstring := false;
- while ((i >= 1) and not(endofstring)) do
- if (tempStr[i] = ' ') then
- i := i - 1
- else
- endofstring := true;
-
- LenString := i;
- end;
-
-
- { Copy command line into temporary string until either EOS or blank }
-
- procedure SkipBlanks(var command : string80;
- var commandLen : integer);
-
- var
- i, k, j, oldComLen : integer;
- endOfString : boolean;
-
- begin
-
- i := 1;
- endofString := false;
- oldComLen := commandLen;
- while ((i <= commandLen) and (not(endofString))) do
- if (command[i] = ' ') then
- i := i + 1
- else
- endofString := true;
-
- k := 1;
- for j:=i to commandLen do
- begin
- command[k] := command[j];
- k := k + 1;
- end;
-
- if ((oldComLen = 1) and (i <> 1)) then
- commandLen := commandLen - i
- else
- commandLen := commandLen - (i-1);
- end;
-
-
- { Copy command line into temporary string until either EOS or blank }
-
- procedure CopyToken(var command : string80;
- var commandLen : integer;
- var tempStr : string13;
- var totChars : integer);
-
- const
- { %include 'CURRENT_CONSTANT' (lines 2418-2583}
- NULLTOKE = 100;
- RANGENULL = 101;
- KERMITPROMPT = 'Kermit-CP6>';
- KERMITHELP = 'KERMITHLP:';
-
- INVALIDCOMMAND = 1;
- INVALIDSETCOMMAND = 2;
- INVALIDSHOWCOMMAND = 3;
- NOTIMPLEMENTED = 4;
- INVALIDFILESPEC = 5;
- INVALIDSETCVALUE = 6;
- INVALIDSETDVALUE = 7;
- INVALIDSETOVALUE = 8;
- INVALIDSETRANGE = 9;
- SENDPARMS = 10;
- RECEIVEPARMS = 11;
- LOCALPARMS = 12;
- BLANKLINE = 13;
- NOHELPAVAILABLE = 14;
- IBEXSPAWNFAILED = 15;
-
- cSET = 'SET ';
- cSHOW = 'SHOW ';
- cSTATUS = 'STATUS ';
- cCONNECT = 'CONNECT ';
- cHELP = 'HELP ';
- cEXIT = 'EXIT ';
- cQUIT = 'QUIT ';
- cQUESTION = '? ';
- cSEND = 'SEND ';
- cRECEIVE = 'RECEIVE ';
- cDEBUGGING = 'DEBUGGING ';
- cLOCALECHO = 'LOCAL-ECHO ';
- cDELAY = 'DELAY ';
- cPACKETLENGTH = 'PACKET-LENGTH';
- cPADDING = 'PADDING ';
- cPADCHAR = 'PADCHAR ';
- cTIMEOUT = 'TIMEOUT ';
- cENDOFLINE = 'END-OF-LINE ';
- cQUOTE = 'QUOTE ';
- cALL = 'ALL ';
- cON = 'ON ';
- cOFF = 'OFF ';
- cBADTOKEN = 'XX ';
- cTRANSMODE = 'TRANSMODE ';
- cASCII = 'ASCII ';
- cBINARY = 'BINARY ';
- cEIGHTQUOTE = 'EIGHT-QUOTE ';
- cFILERECORD = 'FILERECORD ';
- cCR = 'CR ';
- cLF = 'LF ';
- cCRLF = 'CRLF ';
- cPARITY = 'PARITY ';
- cEVEN = 'EVEN ';
- cODD = 'ODD ';
- cNONE = 'NONE ';
- cSPEED = 'SPEED ';
- cIBEX = 'IBEX ';
-
- uSET = 3;
- uMSEND = 3;
- uMRECEIVE = 1;
- uSHOW = 2;
- uSTATUS = 2;
- uCONNECT = 1;
- uIBEX = 1;
- uHELP = 1;
- uQUESTION = 1;
- uEXIT = 1;
- uQUIT = 1;
- uSEND = 1;
- uRECEIVE = 1;
- uDEBUGGING = 3;
- uFILERECORD = 1;
- uTRANSMODE = 1;
- uLOCALECHO = 2;
- uDELAY = 3;
- uPACKETLENGTH = 3;
- uPADDING = 4;
- uPADCHAR = 4;
- uTIMEOUT = 1;
- uENDOFLINE = 1;
- uQUOTE = 1;
- uALL = 1;
- uON = 2;
- uOFF = 2;
- uBADTOKEN = 1;
- uCR = 2;
- uLF = 1;
- uCRLF = 2;
- uPARITY = 1;
- uEVEN = 1;
- uODD = 1;
- uNONE = 1;
- uSPEED = 2;
- uASCII = 1;
- uBINARY = 1;
- uQUOTED = 1;
- uEIGHTQUOTE = 1;
-
- oON = 0;
- oOFF = 1;
- oEVEN = 2;
- oODD = 3;
- oNONE = 4;
- oSET = 5;
- oSHOW = 6;
- oSTATUS = 7;
- oCONNECT = 8;
- oHELP = 9;
- oEXIT = 10;
- oQUIT = 11;
- oSEND = 12;
- oRECEIVE = 13;
- oDEBUGGING = 14;
- oLOCALECHO = 15;
- oDELAY = 16;
- oPACKETLENGTH = 17;
- oPADDING = 18;
- oPADCHAR = 19;
- oTIMEOUT = 20;
- oENDOFLINE = 21;
- oQUOTE = 22;
- oQUESTIONM = 23;
- oALL = 24;
- oBADTOKEN = 25;
- oFILERECORD = 26;
- oCR = 27;
- oLF = 28;
- oCRLF = 29;
- oPARITY = 30;
- oSPEED = 31;
- oIBEX = 32;
- oTRANSMODE = 33;
- oASCII = 34;
- oBINARY = 35;
- oEIGHTQUOTE = 36;
- oXXXX = 100 ;
-
- oMAINTYPE = 1;
- oSETTYPE = 2;
- oSHOWTYPE = 3;
- oSENDTYPE = 4;
- oRECEIVETYPE = 5;
- oDEBUGTYPE = 6;
- oFILERECTYPE = 8;
- oLOCECHOTYPE = 9;
- oPARITYTYPE = 10;
- oTRANSTYPE = 11;
-
- DECIMAL = 0;
- SDECIMAL = 1;
- OCTAL = 2;
- CHRACTER = 3;
- IDECIMAL = 4;
- EBCHRACTER = 5;
-
- oASCSTATE = 1;
- oBINSTATE = 0;
-
- o300BAUD = 300;
- o600BAUD = 600;
- o1200BAUD = 1200;
- o2400BAUD = 2400;
- o4800BAUD = 4800;
- o9600BAUD = 9600;
-
- var
- i, j, k : integer;
- noBlank : boolean;
- tempToken : string80;
-
- begin
-
- for i:=1 to SMALLSIZE do
- tempStr[i] := ' ';
-
- i := 1;
- noblank := true;
- while ((i <= commandLen) and (noblank)) do
- if (command[i] <> ' ') then
- begin
- tempToken[i] := command[i];
- i := i + 1;
- end
- else
- noBlank := false;
-
- totChars := i - 1;
-
- if (totChars <= SMALLSIZE) then
- for i:=1 to totChars do
- tempStr[i] := tempToken[i]
- else
- begin
- totChars := 2;
- tempStr := cBADTOKEN;
- end;
-
- k := 1;
- for j:=(totChars+1) to commandLen do
- begin
- command[k] := command[j];
- k := k + 1;
- end;
-
- commandLen := commandLen - totChars;
- end;
-
-
- { Routine to compare strings for symbol comparison. }
-
- function CompareStr(command, symbol : string13;
- commandLen, symbolLen : integer) : boolean;
-
- var
- i : integer;
- sameStr : boolean;
-
- begin
- sameStr := true;
- i := 1;
- while (sameStr and (i <= commandLen)) do
- if command[i] <> symbol[i] then
- sameStr := false
- else
- i := i + 1;
- i := i - 1;
-
- CompareStr := sameStr and (i >= symbolLen);
- end;
-
-
- procedure StrUpcase(var command : string80;
- commandLen : integer);
-
- var
- i, diff : integer;
-
- begin
- diff := ord('a') - ord('A');
- for i:=1 to commandLen do
- if ((command[i] >= 'a') and (command[i] <= 'z')) then
- command[i] := chr(ord(command[i]) - diff);
- end;
-
-
- function IsNumeric(token : string13;
- var tokLen, value : integer;
- typeToken : integer) : boolean;
-
-
- var
- goodChar : boolean;
- upBound : char;
- base, i : integer;
-
- begin
-
- value := 0;
- i := 1;
- goodChar := true;
- upBound := '9';
- base := 10;
- if (typeToken = OCTAL) then
- begin
- upBound := '7';
- base := 8;
- end;
-
- while ((i <= tokLen) and (goodChar)) do
- if ((token[i] >= '0') and (token[i] <= upBound)) then
- begin
- value := (value*base) + (ord(token[i]) - ord('0'));
- i := i + 1;
- end
- else
- begin
- goodChar := false;
- value := 0;
- end;
-
- goodChar := goodChar and (tokLen > 0);
-
- if (typeToken = OCTAL) then
- IsNumeric := goodChar and ((value >= 0) and (value <= 31))
- else
- if (typeToken = SDECIMAL) then
- IsNumeric := goodChar and ((value >= MINPACKETSIZE) and
- (value <= MAXPACKETSIZE))
- else
- if (typeToken = IDECIMAL) then
- IsNumeric := goodChar and ((value = o300BAUD)
- or (value=o600BAUD) or (value = o1200BAUD)
- or (value=o2400BAUD) or (value = o4800BAUD)
- or (value = o9600BAUD))
- else
- IsNumeric := goodChar and ((value >= 0) and
- (value <= 99))
-
- end;
-
-
- { Print the ? help message for set menu. }
-
- procedure PrintSetHelp;
- begin
- writeln;
- writeln;
- writeln('*** HELP ==>');
- writeln;
- writeln(' SET keyword');
- writeln;
- writeln(' Keywords:');
- writeln(' SEND <option>');
- writeln(' RECEIVE <option>');
- writeln(' TRANSMODE <ASCII | binary>');
- writeln(' EIGHT-QUOTE <character>');
- writeln(' FILERECORD <CRLF | lf | cr>');
- writeln(' PARITY <NONE | even | odd>');
- writeln(' DEBUGGING <on | OFF>');
- writeln(' SPEED <decimal>');
- writeln(' DELAY <decimal>');
- writeln;
- writeln('*** END-OF-MESSAGE');
- writeln;
- writeln;
- end;
-
-
- { Print the ? help message for show menu. }
-
- procedure PrintShowHelp;
- begin
- writeln;
- writeln;
- writeln('*** HELP ==>');
- writeln;
- writeln(' SHOW keyword');
- writeln;
- writeln(' Keywords:');
- writeln(' SEND <option>');
- writeln(' RECEIVE <option>');
- writeln(' TRANSMODE');
- writeln(' EIGHT-QUOTE');
- writeln(' FILERECORD');
- writeln(' DEBUGGING');
- writeln(' SPEED');
- writeln(' DELAY');
- writeln(' ALL');
- writeln;
- writeln('*** END-OF-MESSAGE');
- writeln;
- writeln;
- end;
-
-
- { Print the ? help message for set send/receive menu. }
-
- procedure PrintSetSendReceiveHelp;
- begin
- writeln;
- writeln;
- writeln('*** HELP ==>');
- writeln;
- writeln(' SET SEND/RECEIVE keyword');
- writeln;
- writeln(' Keywords:');
- writeln(' PACKET-LENGTH <decimal>');
- writeln(' PADDING <decimal>');
- writeln(' PADCHAR <octal value>');
- writeln(' TIMEOUT <decimal>');
- writeln(' END-OF-LINE <octal value>');
- writeln(' QUOTE <character>');
- writeln;
- writeln('*** END-OF-MESSAGE');
- writeln;
- writeln;
- end;
-
-
- { Print the ? help message for show send/receive menu. }
-
- procedure PrintShowSendReceiveHelp;
- begin
- writeln;
- writeln;
- writeln('*** HELP ==>');
- writeln;
- writeln(' SHOW SEND/RECEIVE keyword');
- writeln;
- writeln(' Keywords:');
- writeln(' PACKET-LENGTH');
- writeln(' PADDING');
- writeln(' PADCHAR');
- writeln(' TIMEOUT');
- writeln(' END-OF-LINE');
- writeln(' QUOTE');
- writeln;
- writeln('*** END-OF-MESSAGE');
- writeln;
- writeln;
- end;
-
-
- procedure PrintStatus;
- { Print the status of the last send/receive. }
-
- const
- STRWIDTH = 7;
-
- var
- overHead, effectiveRate : integer;
- begin
- writeln(' Packets Sent = ', NumSendPacks : STRWIDTH);
- if (oldRunType = Transmit) then
- begin
- writeln(' Number of ACK packets = ', NumACKrecv : STRWIDTH);
- writeln(' Number of NAK packets = ', NumNAKrecv : STRWIDTH);
- writeln(' Number of BAD packets = ', NumBADrecv : STRWIDTH);
- end
- else
- begin
- writeln(' Number of ACK packets = ', NumACK : STRWIDTH);
- writeln(' Number of NAK packets = ', NumNAK : STRWIDTH);
- end;
- writeln(' Data characters Sent = ', ChInFileSend : STRWIDTH);
- writeln(' Total characters Sent = ', ChInPackSend : STRWIDTH);
- OverHd(ChInPackSend, ChInFileSend, overHead);
- writeln(' Overhead on Send Packets = ', overHead : STRWIDTH, ' %');
- writeln(' ');
- writeln(' Packets Received = ', NumRecvPacks : STRWIDTH);
- writeln(' Data characters Received = ', ChInFileRecv : STRWIDTH);
- writeln(' Total characters Received = ', ChInPackRecv : STRWIDTH);
- OverHd(ChInPackRecv, ChInFileRecv, overHead);
- writeln(' Overhead on Receive Packets = ', overHead : STRWIDTH, ' %');
-
- writeln;
-
- end;
-
-
- { Print the message specified. }
-
- procedure PrintMessage(messageNumber : integer);
-
-
- begin
- case messageNumber of
- NOTIMPLEMENTED :
- writeln(' ? Not Implemented');
- INVALIDCOMMAND :
- writeln(' ? Invalid command');
- INVALIDSETCOMMAND :
- writeln(' ? Invalid set command');
- INVALIDSHOWCOMMAND :
- writeln(' ? Invalid show command');
- INVALIDFILESPEC :
- writeln(' ? Invalid file specification');
- INVALIDSETCVALUE :
- writeln(' ? Bad value: character');
- INVALIDSETDVALUE :
- writeln(' ? Bad value: decimal');
- INVALIDSETOVALUE :
- writeln(' ? Bad value: octal');
- INVALIDSETRANGE :
- writeln(' ? Value not in accepted range');
- NOHELPAVAILABLE :
- writeln(' ? Not a HELP subject');
- IBEXSPAWNFAILED :
- writeln(' ? IBEX spawn failed');
- SENDPARMS :
- writeln('Send Parameters:');
- RECEIVEPARMS :
- writeln('Receive Parameters:');
- LOCALPARMS :
- writeln('Local System Parameters:');
- BLANKLINE :
- writeln(' ');
- end;
- end;
-
-
- procedure ExecShell(dclcommd : string80;
- commdLen : integer);
- { Call the IBEX shell }
-
- const
- SPAWN = 'SPAWN';
- BLANK = ' ';
- MAXCOMMD = 60;
-
- var
- status, i : integer;
- shellLine : NewString80;
-
- begin
-
- PrintMessage(NOTIMPLEMENTED);
-
- end;
-
- procedure ScanForToken(var commandLine:String80;
- var commandLen, token: integer;
- typeToken:integer);forward;
-
-
-
- { Print out appropriate help message according to the code
- received from either HELPSetShow or PrintHelpCP6. }
-
- procedure HelpMessage(code : integer);
- begin
- writeln;
- writeln;
- writeln('*** HELP ==>');
- case code of
- 1 : begin
- writeln(' SHOW SEND PACKET-LENGTH par');
- writeln;
- writeln(' Description:');
- write(' This command shows the send ');
- writeln('packet length.');
- writeln(' par:');
- write(' may be any decimal value between ');
- writeln('10 and 96');
- writeln(' Default Value = 94');
- writeln;
- writeln(' Note that SETting this will have no effect since');
- writeln(' the remote Kermit will send the value it requires.');
- writeln;
- writeln(' Affect this change by SETting the RECEIVE PACKET-LENGTH');
- writeLN(' parameter of the remote Kermit.');
- writeln;
- writeln(' Example:');
- writeln(' KERMIT-CP6> SHOW SEND PACKET-LENGTH');
- writeln(' KERMIT-IBM> SET RECEIVE PACKET-LENGTH 80');
- end;
- 2 : begin
- writeln;
- writeln(' SHOW SEND PADDING ');
- writeln;
- writeln(' Description:');
- write(' This command shows the number of ');
- writeln('padding characters that will be ');
- writeln(' sent to the remote Kermit. ');
- writeln;
- writeln(' Note that SETting this will have no effect since');
- writeln(' the remote Kermit will send the value it requires.');
- writeln;
- writeln(' Affect this change by SETting the RECEIVE PADDING');
- writeln(' parameter of the remote Kermit.');
- writeln;
- writeln(' Example:');
- writeln(' KERMIT-CP6> SHOW SEND PADDING');
- writeln(' KERMIT-IBM> SET RECEIVE PADDING 30');
- end;
- 3 : begin
- writeln;
- writeln(' SHOW SEND PADCHAR ');
- writeln;
- writeln(' Description:');
- write(' This command shows the character ');
- writeln('that will be sent ');
- writeln(' as padding to the remote Kermit. ');
- writeln;
- writeln(' Note that SETting this parameter will have no effect since');
- writeln(' the remote Kermit will send the value it requires.');
- writeln;
- writeln(' Example:');
- writeln(' KERMIT-CP6> SHOW SEND PADCHAR');
- end;
- 4 : begin
- writeln;
- writeln(' SHOW SEND TIMEOUT par');
- writeln;
- writeln(' Description:');
- writeln(' This command shows the number of seconds Kermit CP6');
- writeln(' will wait for a response to a packet sent to the remote Kermit.');
- writeln(' The SEND is terminated if a timeout occurs.');
- writeln(' par:');
- write(' may be any positive decimal number, ');
- writeln('given in seconds');
- writeln(' Default value = 20 seconds');
- writeln;
- writeln(' Note that SETting this will have no effect since');
- writeln(' the remote Kermit will send the value it requires.');
- writeln;
- writeln(' Affect this change by SETting the RECEIVE TIMEOUT');
- writeln(' parameter of the remote Kermit.');
- writeln;
- writeln(' Example:');
- writeln(' KERMIT-CP6> SHOW SEND TIMEOUT');
- writeln(' KERMIT-IBM> SET RECEIVE TIMEOUT 10');
- end;
- 5 : begin
- writeln;
- writeln(' SET/SHOW SEND END-OF-LINE par');
- writeln;
- writeln(' Description:');
- write(' This command sets/shows the end of line');
- writeln(' character that KERMITCP6 will ');
- writeln(' send to the remote Kermit.');
- writeln;
- writeln(' par:');
- write(' may be any ASCII value for a character, ');
- writeln('given in octal');
- writeln(' Default value = 15 (ASCII CR, CTRL-M)');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SET SEND END-OF-LINE 12');
- writeln(' KERMIT-CP6> SHOW SEND END-OF-LINE');
- end;
- 6 : begin
- writeln;
- writeln(' SET/SHOW SEND QUOTE par');
- writeln;
- writeln(' Description:');
- write(' This command sets/shows the printable ');
- writeln('character that KERMITCP6 will ');
- write(' send to the remote Kermit to prefix');
- writeln(' control characters.');
- writeln(' par:');
- writeln(' may be any printable character');
- writeln(' Default value = "#" (ASCII 35(dec) )');
- writeln(' NOTE: Change the quote character to send ');
- writeln(' CP6 files with many ''#'' characters.');
- writeln(' Affect this change by');
- write(' SETting the RECEIVE QUOTE parameter');
- writeln(' of the remote KERMIT,');
- write(' the SEND QUOTE parameter');
- writeln(' of the remote KERMIT, and');
- write(' the SEND QUOTE parameter');
- writeln(' of CP6 KERMIT to the same value.');
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SHOW SEND QUOTE');
- writeln(' KERMIT-CP6> SET SEND QUOTE +');
- writeln(' KERMIT-IBM> SET SEND QUOTE 43 (The ASCII value of ''+'' is 43.) ');
- writeln(' KERMIT-IBM> SET RECEIVE QUOTE 43');
- end;
- 7 : begin
- writeln(code)
- end;
- 8 : begin
- writeln;
- writeln(' SET/SHOW RECEIVE PACKET-LENGTH par');
- writeln;
- writeln(' Description:');
- writeln(' This command sets/shows the maximum of characters');
- writeln(' in a message received by KermitCP6.');
- writeln;
- writeln(' par:');
- write(' may be any decimal value between ');
- writeln('10 and 96');
- writeln(' Default Value = 94');
- writeln;
- writeln(' Examples: ');
- writeln(' KERMIT-CP6> SET RECEIVE PACKET-LENGTH 60');
- writeln(' KERMIT-CP6> SHOW RECEIVE PACKET-LENGTH');
- end;
- 9 : begin
- writeln;
- writeln(' SET/SHOW RECEIVE PADDING par');
- writeln;
- writeln(' Description:');
- write(' This command sets/shows the number of ');
- writeln('padding characters that will ');
- writeln(' precede a message received by KERMITCP6.');
- writeln;
- writeln(' par:');
- writeln(' may be any positive decimal number');
- writeln(' Default value = 0');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SET RECEIVE PADDING 5');
- writeln(' KERMIT-CP6> SHOW RECEIVE PADDING');
- end;
- 10 : begin
- writeln;
- writeln(' SET/SHOW RECEIVE PADCHAR par');
- writeln;
- writeln(' Description:');
- write(' This command sets/shows the character ');
- writeln('that will precede ');
- writeln(' a message received by KERMITCP6.');
- writeln(' See SET RECEIVE PADDING.');
- writeln;
- writeln(' par:');
- writeln(' may be any ASCII value, given as an octal ');
- writeln(' number in the range: 0-37, or 177');
- writeln(' Default value = 0 (ASCII NUL)');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SET RECEIVE PADCHAR 15');
- writeln(' KERMIT-CP6> SHOW RECEIVE PADCHAR');
- end;
- 11 : begin
- writeln;
- writeln(' SET/SHOW RECEIVE TIMEOUT par');
- writeln;
- writeln(' Description:');
- write(' This command sets/shows the number of ');
- writeln('seconds KERMITCP6 will ');
- writeln(' wait while attempting to receive a message from the remote Kermit.');
- writeln;
- writeln(' par:');
- write(' may be any positive decimal number, ');
- writeln('given in seconds');
- writeln(' Default value = 20 seconds');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SET RECEIVE TIMEOUT 15');
- writeln(' KERMIT-CP6> SHOW RECEIVE TIMEOUT');
- end;
- 12 : begin
- writeln;
- writeln(' SET/SHOW RECEIVE END-OF-LINE par');
- writeln;
- writeln(' Description:');
- write(' This command sets/shows the end of line');
- writeln(' character that KERMITCP6 will ');
- writeln(' expect to receive from the remote Kermit.');
- writeln;
- writeln(' par:');
- write(' may be any ASCII value for a character, ');
- writeln('given in octal');
- writeln(' Default value = 15 (ASCII CR, CTRL-M)');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SET RECEIVE END-OF-LINE 12');
- writeln(' KERMIT-CP6> SHOW RECEIVE END-OF-LINE');
- end;
- 13 : begin
- writeln;
- writeln(' SET/SHOW RECEIVE QUOTE par');
- writeln;
- writeln(' Description:');
- writeln(' This command sets/shows the printable character KermitCP6 expects');
- writeln(' to be prefixed to the control characters of messages sent');
- writeln(' by the remote Kermit.');
- writeln(' par:');
- writeln(' may be any printable character');
- writeln(' Default value = "#" (ASCII 35(dec) )');
- writeln(' NOTE: Change the quote character to receive remote Kermit');
- writeln(' files with many ''#'' characters.');
- writeln(' Affect this change by SETting');
- writeln(' the SEND QUOTE parameter of the remote Kermit,');
- writeln(' the SEND QUOTE parameter of CP6 Kermit, and');
- writeln(' the RECEIVE QUOTE parameter of CP6 Kermit to the same value.');
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SHOW SEND QUOTE');
- writeln(' KERMIT-CP6> SET RECEIVE QUOTE +');
- writeln(' KERMIT-CP6> SET SEND QUOTE +');
- writeln(' KERMIT-IBM> SET SEND QUOTE 43 (The ASCII value of ''+'' is 43.)');
- end;
- 14 : begin
- writeln(code)
- end;
- 15 : begin
- writeln;
- writeln(' SET/SHOW TRANSMODE par');
- writeln;
- writeln(' Description:');
- write(' This command sets/shows the type of ');
- writeln('file that KERMITCP6 ');
- writeln(' will receive.');
- writeln;
- writeln(' par:');
- writeln(' must be one of the following...');
- writeln(' ASCII - for text files');
- writeln(' BINARY - for non-text files');
- writeln(' Default value = ASCII');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SET TRANSMODE BINARY');
- writeln(' KERMIT-CP6> SHOW TRANSMODE');
- end;
- 16 : begin
- writeln;
- writeln(' SET/SHOW EIGHT-QUOTE par');
- writeln;
- writeln(' Description:');
- write(' This command sets/shows the character ');
- writeln('that KERMITCP6 will send ');
- write(' to the remote Kermit as a quote for');
- writeln(' eight-bit characters.');
- writeln;
- writeln(' par:');
- writeln(' may be any printable character');
- writeln(' Default value = "&" (ASCII 38(dec) )');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SET EIGHT-QUOTE %');
- writeln(' KERMIT-CP6> SHOW EIGHT-QUOTE');
- end;
- 17 : begin
- writeln;
- writeln(' SET/SHOW DEBUGGING par');
- writeln;
- writeln(' Description:');
- writeln(' This command sets/shows the state of KermitCP6''s debugging');
- writeln(' messages. When on, messages are sent to the user''s terminal.');
- writeln(' Redirect messages to a CP6 file by using an');
- writeln(' IBEX SET command ''!SET DEBUGGING fid, CTG=YES''.');
- writeln;
- writeln(' par:');
- writeln(' must be ON or OFF');
- writeln(' Default value = OFF');
- writeln(' NOTE: Debugging is only meaningful for modification of Kermit code.');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SET DEBUGGING ON');
- writeln(' KERMIT-CP6> SHOW DEBUGGING');
- end;
- 18 : begin
- writeln;
- writeln(' SET/SHOW FILERECORD par');
- writeln;
- writeln(' Description:');
- writeln(' This command sets/shows the end of line character being used ');
- writeln(' to separate records in a file being sent from CP6 ');
- writeln(' to the remote Kermit.');
- writeln;
- writeln(' par:');
- writeln(' must be one of the following ...');
- writeln(' CR - a carriage return');
- writeln(' LF - a line feed');
- write(' CRLF - a carriage return, ');
- writeln('followed by a linefeed');
- writeln(' Default value = CRLF');
- writeln;
- writeln(' SUGGESTED USE:');
- writeln(' SET FILERECORD LF to transmit a PASCAL source to an APPLE IIe.');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SET FILERECORD LF');
- writeln(' KERMIT-CP6> SHOW FILERECORD');
- end;
- 19 : begin
- end;
- 20 : begin
- writeln;
- writeln(' SET/SHOW PARITY par');
- writeln;
- writeln(' Description:');
- write(' This command sets/shows the type of ');
- writeln('parity being used on the ');
- writeln(' the transmission line.');
- writeln;
- writeln(' par:');
- writeln(' must be EVEN, ODD, or NONE');
- write(' Default value = NONE (others require ');
- writeln('eight-bit prefixing ');
- writeln(' for binary files)');
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SET PARITY EVEN');
- writeln(' KERMIT-CP6> SHOW PARITY');
- end;
- 21 : begin
- writeln;
- writeln(' SHOW SPEED ');
- writeln;
- writeln(' Description:');
- write(' This command shows the baud rate ');
- writeln('of transmission.');
- writeln;
- writeln(' NOTE: SPEED must be SET by the microcomputer Kermit.');
- writeln;
- writeln(' Example:');
- writeln(' KERMIT-CP6> SHOW SPEED');
- end;
- 22 : begin
- writeln;
- writeln(' SET/SHOW DELAY par');
- writeln;
- writeln(' Description:');
- write(' This command sets/shows the number ');
- writeln('of seconds KERMITCP6 will ');
- write(' wait before sending data following ');
- writeln('a SEND command.');
- writeln;
- writeln(' par:');
- write(' may be any positive decimal number, ');
- writeln('given in seconds');
- writeln(' Default value = 5 seconds');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SET DELAY 25');
- writeln(' KERMIT-CP6> SHOW DELAY');
- writeln(' NOT YET IMPLEMENTED !!');
- end;
- 23 : begin
- writeln(code)
- end;
- 24 : begin
- writeln;
- writeln(' SHOW ALL');
- writeln;
- writeln(' Description:');
- writeln(' This command shows the current values of the KermitCP6');
- writeln(' SEND, RECEIVE, and Local System parameters.');
- writeln;
- writeln(' Example:');
- writeln(' KERMIT-CP6> SHOW ALL');
- end;
- 25 : begin
- writeln;
- writeln(' SEND filespec');
- writeln;
- writeln(' Description:');
- write(' This command will send the specified ');
- writeln('CP6 file to the remote ');
- writeln(' Kermit.');
- writeln;
- writeln(' filespec:');
- writeln(' any valid, existing CP6 file-specification.');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> SEND MYFILE');
- writeln(' KERMIT-CP6> SEND ANOTHER_FILE');
- end;
- 26 : begin
- writeln;
- writeln(' RECEIVE filespec');
- writeln;
- writeln(' Description:');
- write(' This command will prepare KERMITCP6 ');
- writeln('to receive a file being ');
- writeln(' sent by the remote Kermit.');
- writeln;
- writeln(' filespec:');
- writeln(' any valid CP6 file-specification. ');
- write(' if omitted, the file-specification ');
- writeln('will be obtained from the ');
- write(' file header sent by the remote ');
- writeln('Kermit.');
- writeln;
- writeln(' WARNING! KERMIT will overwrite an existing');
- writeln(' file with the given filespec.');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> RECEIVE MYFILE');
- writeln(' KERMIT-CP6> RECEIVE');
- end;
- 27 : begin
- writeln;
- writeln(' STATUS');
- writeln;
- writeln(' Description:');
- writeLN(' This command will display information ');
- writeln(' on the most recent transmission of data.');
- writeln;
- writeln(' Example:');
- writeln(' KERMIT-CP6> STATUS');
- end;
- 28 : begin
- end;
- 29 : begin
- writeln;
- writeln(' The following are valid KERMIT-CP6 commands:');
- writeln;
- write(' STATUS HELP EXIT QUIT');
- writeln(' RECEIVE SEND ');
- writeln(' SET SHOW ');
- writeln;
- write(' In order to use the HELP facilities on ');
- writeln('KERMIT-CP6, type ''HELP command''. ');
- write(' Abbreviated HELP can be obtained on selected');
- writeln(' commands by typing ''command ?''.');
- end;
- 30 : begin
- writeln;
- writeln(' EXIT/QUIT');
- writeln;
- writeln(' Description:');
- write(' This command allows the user to ');
- writeln('exit KERMITCP6 and return to IBEX.');
- writeln;
- writeln(' Examples:');
- writeln(' KERMIT-CP6> QUIT');
- writeln(' KERMIT-CP6> EXIT');
- end;
- 31 : begin
- writeln(code)
- end;
- 32 : begin
- writeln(code)
- end
- end; {of case code of}
- writeln;
- writeln('*** END-OF-MESSAGE');
- writeln
- end;
-
- { Parse the help set/show command and print the appropriate
- help message. }
-
- procedure HELPSetShow(var commandLine : string80;
- var commandLen : integer;
- commandType : integer);
-
-
- var
- token : integer;
-
- begin
- ScanForToken(commandLine, commandLen, token, commandType);
-
- if (token in [oSEND, oRECEIVE, oDEBUGGING, oDELAY,
- oQUESTIONM, oALL, oFILERECORD, oPARITY, oSPEED,
- oTRANSMODE, oEIGHTQUOTE]) or (token = NULLTOKE) then
- case token of
- oSEND :
- begin
- ScanForToken(commandLine, commandLen, token, oSENDTYPE);
- { This next line checks if token is oPACKETLENGTH, oPADDING,
- oPADCHAR, oTIMEOUT, oENDOFLINE, oQUOTE, or oQUESTIONM. }
- if ((token>=oPACKETLENGTH) and (token<=oQUESTIONM)) or
- (token = NULLTOKE) then
- case token of
- oPACKETLENGTH : HelpMessage(1);
- oPADDING : HelpMessage(2);
- oPADCHAR : HelpMessage(3);
- oTIMEOUT : HelpMessage(4);
- oENDOFLINE : HelpMessage(5);
- oQUOTE : HelpMessage(6);
- oQUESTIONM,
- NULLTOKE : if commandType = oSETTYPE then
- PrintSetSendReceiveHelp
- else
- PrintShowSendReceiveHelp;
- end { inner case token of }
- else
- begin
- PrintMessage(NOHELPAVAILABLE);
- HelpMessage(29)
- end
- end; {of oSEND case}
-
- oRECEIVE :
- begin
- ScanForToken(commandLine, commandLen, token, oRECEIVETYPE);
- { This next line checks if token is oPACKETLENGTH, oPADDING,
- oPADCHAR, oTIMEOUT, oENDOFLINE, oQUOTE, or oQUESTIONM. }
- if ((token>=oPACKETLENGTH) and (token<=oQUESTIONM)) or
- (token = NULLTOKE) then
- case token of
- oPACKETLENGTH : HelpMessage(8);
- oPADDING : HelpMessage(9);
- oPADCHAR : HelpMessage(10);
- oTIMEOUT : HelpMessage(11);
- oENDOFLINE : HelpMessage(12);
- oQUOTE : HelpMessage(13);
- oQUESTIONM,
- NULLTOKE : if commandType = oSETTYPE then
- PrintSetSendReceiveHelp
- else
- PrintShowSendReceiveHelp;
- end {inner case token of}
- else
- begin
- PrintMessage(NOHELPAVAILABLE);
- HelpMessage(29);
- end
- end; {of oRECEIVE case}
-
- oTRANSMODE : HelpMessage(15);
- oEIGHTQUOTE : HelpMessage(16);
- oDEBUGGING : HelpMessage(17);
- oFILERECORD : HelpMessage(18);
- oPARITY : HelpMessage(20);
- oSPEED : HelpMessage(21);
- oDELAY : HelpMessage(22);
- oALL : if commandType = oSHOWTYPE then
- HelpMessage(24)
- else
- begin
- PrintMessage(NOHELPAVAILABLE);
- PrintSetHelp
- end;
- oQUESTIONM,
- NULLTOKE : if commandType = oSETTYPE then
- PrintSetHelp
- else
- PrintShowHelp;
- end { of outer case token of }
- else
- begin
- PrintMessage(NOHELPAVAILABLE);
- HelpMessage(29)
- end
- end;
-
-
-
-
-
-
-
- { Routine to print appropriate help message.
- Determines token following help. }
-
- procedure PrintHelpCP6(var commandLine : String80;
- var commandLen : integer);
-
-
- var
- token : integer;
-
-
- begin
- ScanForToken(commandLine, commandLen, token, oMAINTYPE);
- { Make HELP and HELP HELP equivalent statements. }
- if token = NULLTOKE then
- token := oHELP;
- if token in [oSET, oSHOW, oSTATUS, oHELP, oEXIT,
- oQUIT, oSEND, oRECEIVE, oQUESTIONM] then
- case token of
- oSET : HELPSetShow(commandLine, commandLen, oSETTYPE);
- oSHOW : HELPSetShow(commandLine, commandLen, oSHOWTYPE);
- oSEND : HelpMessage(25);
- oRECEIVE : HelpMessage(26);
- oSTATUS : HelpMessage(27);
- oHELP,
- oQUESTIONM : HelpMessage(29);
- oEXIT,
- oQUIT : HelpMessage(30);
- end { of case token of }
- else
- begin
- PrintMessage(NOHELPAVAILABLE);
- HelpMessage(29);
- end
- end;
-
-
-
-
- { Routine to print parameter values. }
-
- procedure PrintParmValue(value, token : integer);
-
-
- begin
- case token of
- oPACKETLENGTH :
- writeln(' Packet-Length = ', value : 2, ' (dec)');
- oPADDING :
- writeln(' Padding = ', value : 2, ' (dec)');
- oPADCHAR :
- writeln(' Padding Character = ', value, ' (decimal)');
- oTIMEOUT :
- writeln(' Time-out length = ', value : 2, ' (sec)');
- oENDOFLINE :
- writeln(' End of Line Character = ', value, ' (decimal)');
- oQUOTE :
- writeln(' Quote Character = ', chr(value));
- oTRANSMODE :
- begin
- write(' File Transfer Type = ');
- if (value = oASCII) then
- writeln('ascii')
- else
- writeln('binary');
- end;
- oEIGHTQUOTE :
- writeln(' Eight-Bit Quote = ', chr(value));
- oFILERECORD :
- begin
- write(' End of Line for file = ');
- if (value = oCR) then
- writeln('cr')
- else
- if (value = oLF) then
- writeln('lf')
- else
- writeln('cr/lf');
- end;
- oDELAY :
- writeln(' Delay = ', value : 2, ' (sec)');
- oDEBUGGING :
- begin
- write(' Debugging = ');
- if (value = oOFF) then
- writeln('off')
- else
- writeln('on');
- end;
- oPARITY :
- begin
- write(' Parity = ');
- if (value = oEVEN) then
- writeln('even')
- else
- if (value = oODD) then
- writeln('odd')
- else
- writeln('none');
- end;
- oSPEED :
- writeln(' Line Speed = ', lSpeed : 4);
- end;
- end;
-
-
- { Routine to scan for an appropriate value }
-
- procedure ScanForValue(var command : string80;
- var commandLen, value : integer;
- convertType, commandType : integer);
-
-
- var
- tempToken : string13;
- totChars : integer;
- badvalue : boolean;
-
- begin
-
- CopyToken(command, commandLen, tempToken, totChars);
-
- case convertType of
- DECIMAL ,
- SDECIMAL,
- IDECIMAL :
- if not(IsNumeric(tempToken, totChars, value, convertType)) and
- (commandType <> oSHOWTYPE) then
- begin
- PrintMessage(INVALIDSETDVALUE);
- value := RANGENULL;
- end;
- OCTAL :
- if not(IsNumeric(tempToken, totChars, value, convertType)) and
- (commandType <> oSHOWTYPE) then
- begin
- PrintMessage(INVALIDSETOVALUE);
- value := RANGENULL;
- end;
- CHRACTER :
- if (totChars = 1) then
- value := ord(tempToken[1])
- else
- if (commandType <> oSHOWTYPE) then
- begin
- PrintMessage(INVALIDSETCVALUE);
- value := RANGENULL;
- end;
- EBCHRACTER :
- begin
- if (totChars = 1) then
- begin
- value := ord(tempToken[1]);
- badvalue := false;
- if (not(value in [EXMARK..RABRACK, GRAVE..TILDE])) then
- badvalue := true;
- end
- else
- badvalue := true;
- if ((commandType <> oSHOWTYPE) and (badvalue)) then
- begin
- PrintMessage(INVALIDSETCVALUE);
- value := RANGENULL;
- end;
- end;
- end;
- end;
-
-
- { Determine if we have a valid number, and if so set it. }
-
- procedure TestAndSetValue(var value, numberToSet : integer;
- token, commandType : integer);
-
-
- begin
- if (commandType = oSHOWTYPE) then
- PrintParmValue(numberToSet, token)
- else
- if (value = NULLTOKE) then
- begin
- PrintMessage(INVALIDSETCOMMAND);
- end
- else
- if (value <> RANGENULL) then
- numberToSet := value;
- end;
-
-
- { Routine to print the value of all parameters in program. }
-
- procedure PrintAllParameters;
-
-
- begin
- PrintMessage(SENDPARMS);
- PrintParmValue(SizeSend, oPACKETLENGTH);
- PrintParmValue(Pad, oPADDING);
- PrintParmValue(PadChar, oPADCHAR);
- PrintParmValue(TheirTimeOut, oTIMEOUT);
- PrintParmValue(SendEOL, oENDOFLINE);
- PrintParmValue(SendQuote, oQUOTE);
-
- PrintMessage(RECEIVEPARMS);
- PrintParmValue(SizeRecv, oPACKETLENGTH);
- PrintParmValue(MyPad, oPADDING);
- PrintParmValue(MyPadChar, oPADCHAR);
- PrintParmValue(MyTimeOut, oTIMEOUT);
- PrintParmValue(MyEOL, oENDOFLINE);
- PrintParmValue(MyQuote, oQUOTE);
-
- PrintMessage(LOCALPARMS);
- PrintParmValue(transtype, oTRANSMODE);
- PrintParmValue(EBQChar, oEIGHTQUOTE);
- PrintParmValue(fileEol, oFILERECORD);
- PrintParmValue(parity, oPARITY);
- PrintParmValue(lSpeed, oSPEED);
- PrintParmValue(Delay, oDELAY);
- PrintParmValue(debugging, oDEBUGGING);
- end;
-
-
- { Routine to parse send/receive command for file name or wildcard des. }
-
- procedure ParseSendReceiveCommand(var commandLine : string80;
- var commandLen : integer;
- var tempFile : string80;
- var token : integer);
-
-
- var
- i : integer;
-
- begin
- for i:=1 to LARGESIZE do
- tempFile[i] := ' ';
-
- if ((commandLine[1] <> ' ') and (commandLen > 0)) then
- begin
-
- if (commandLen > LARGESIZE) then
- commandLen := LARGESIZE;
-
- for i := 1 to commandLen do
- tempFile[i] := commandLine[i];
-
- if (commandLine[1] = '?') then
- begin
- if token = oSEND then
- HelpMessage(25)
- else
- HelpMessage(26);
- token := oXXXX;
- end
- else
- if token = oSEND then
- sFileSpec := oON
- else
- rFileSpec := oON;
- end {end if}
- else
- begin
- if token = oSEND then
- begin
- sFileSpec := oOFF;
- PrintMessage(INVALIDFILESPEC)
- end
- else
- rFileSpec := oOFF
- end; {end if}
-
-
- end;
-
-
- { Get a valid token form the command line and return it. }
- procedure ScanForToken;
-
-
- var
- tempToken : string13;
- totChars : integer;
-
- begin
-
- CopyToken(commandLine, commandLen, tempToken, totChars);
- SkipBlanks(commandLine, commandLen);
-
- token := oBADTOKEN;
- if (totChars <> 0) then
- case typeToken of
- oMAINTYPE :
- if (CompareStr(tempToken, cSET, totChars, uSET)) then
- token := oSET
- else
- if (CompareStr(tempToken, cSHOW, totChars, uSHOW)) then
- token := oSHOW
- else
- if (CompareStr(tempToken, cSTATUS, totChars, uSTATUS)) then
- token := oSTATUS
- else
- if (CompareStr(tempToken, cSEND, totChars, uMSEND)) then
- token := oSEND
- else
- if (CompareStr(tempToken, cRECEIVE, totChars, uMRECEIVE)) then
- token := oRECEIVE
- else
- if (CompareStr(tempToken, cIBEX, totChars, uIBEX)) then
- token := oIBEX
- else
- if (CompareStr(tempToken, cHELP, totChars, uHELP)) then
- token := oHELP
- else
- if (CompareStr(tempToken, cQUESTION, totChars, uQUESTION)) then
- token := oQUESTIONM
- else
- if (CompareStr(tempToken, cQUIT, totChars, uQUIT)) then
- token := oQUIT
- else
- if (CompareStr(tempToken, cEXIT, totChars, uEXIT)) then
- token := oEXIT;
-
- oSETTYPE,
- oSHOWTYPE :
- if (CompareStr(tempToken, cSEND, totChars, uSEND)) then
- token := oSEND
- else
- if (CompareStr(tempToken, cRECEIVE, totChars, uRECEIVE)) then
- token := oRECEIVE
- else
- if (CompareStr(tempToken, cTRANSMODE, totChars, uTRANSMODE)) then
- token := oTRANSMODE
- else
- if (CompareStr(tempToken, cEIGHTQUOTE, totChars, uEIGHTQUOTE)) then
- token := oEIGHTQUOTE
- else
- if (CompareStr(tempToken, cDEBUGGING, totChars, uDEBUGGING)) then
- token := oDEBUGGING
- else
- if (CompareStr(tempToken, cFILERECORD, totChars, uFILERECORD)) then
- token := oFILERECORD
- else
- if (CompareStr(tempToken, cDELAY, totChars, uDELAY)) then
- token := oDELAY
- else
- if (CompareStr(tempToken, cPARITY, totChars, uPARITY)) then
- token := oPARITY
- else
- if (CompareStr(temptoken, cSPEED, totChars, uSPEED)) then
- token := oSPEED
- else
- if (CompareStr(tempToken, cALL, totChars, uALL)) then
- token := oALL
- else
- if (CompareStr(tempToken, cQUESTION, totChars, uQUESTION)) then
- token := oQUESTIONM;
-
- oSENDTYPE,
- oRECEIVETYPE :
- if (CompareStr(tempToken, cPACKETLENGTH, totChars, uPACKETLENGTH)) then
- token := oPACKETLENGTH
- else
- if (CompareStr(tempToken, cPADDING, totChars, uPADDING)) then
- token := oPADDING
- else
- if (CompareStr(tempToken, cQUESTION, totChars, uQUESTION)) then
- token := oQUESTIONM
- else
- if (CompareStr(tempToken, cPADCHAR, totChars, uPADCHAR)) then
- token := oPADCHAR
- else
- if (CompareStr(tempToken, cTIMEOUT, totChars, uTIMEOUT)) then
- token := oTIMEOUT
- else
- if (CompareStr(tempToken, cENDOFLINE, totChars, uENDOFLINE)) then
- token := oENDOFLINE
- else
- if (CompareStr(tempToken, cQUOTE, totChars, uQUOTE)) then
- token := oQUOTE;
-
- oTRANSTYPE :
- if (CompareStr(tempToken, cASCII, totChars, uASCII)) then
- token := oASCII
- else
- if (CompareStr(tempToken, cBINARY, totChars, uBINARY)) then
- token := oBINARY;
-
- oDEBUGTYPE,
- oLOCECHOTYPE :
- if (CompareStr(tempToken, cON, totChars, uON)) then
- token := oON
- else
- if (CompareStr(tempToken, cOFF, totChars, uOFF)) then
- token := oOFF;
-
- oFILERECTYPE :
- if (CompareStr(tempToken, cCR, totChars, uCR)) then
- token := oCR
- else
- if (CompareStr(tempToken, cLF, totChars, uLF)) then
- token := oLF
- else
- if (CompareStr(tempToken, cCRLF, totChars, uCRLF)) then
- token := oCRLF;
-
- oPARITYTYPE :
- if (CompareStr(tempToken, cEVEN, totChars, uEVEN)) then
- token := oEVEN
- else
- if (CompareStr(tempToken, cODD, totChars, uODD)) then
- token := oODD
- else
- if (CompareStr(tempToken, cNONE, totChars, uNONE)) then
- token := oNONE;
- end {of case typeToken of}
- else
- token := NULLTOKE
-
- end;
-
-
- { Parse the set and show command and the proceed to set appropriate
- kermit variables. }
-
- procedure ParseSetShowCommand(var commandLine : string80;
- var commandLen : integer;
- commandType : integer);
-
-
- var
- token, value : integer;
-
- begin
- ScanForToken(commandLine, commandLen, token, commandType);
-
- if token in [oSEND, oRECEIVE, oDEBUGGING, oDELAY,
- oQUESTIONM, oALL, oFILERECORD, oPARITY, oSPEED,
- oTRANSMODE, oEIGHTQUOTE] then
- case token of
- oSEND :
- begin
- ScanForToken(commandLine, commandLen, token, oSENDTYPE);
- { This next line checks if token is oPACKETLENGTH, oPADDING,
- oPADCHAR, oTIMEOUT, oENDOFLINE, oQUOTE, or oQUESTIONM. }
- if ((token>=oPACKETLENGTH) and (token<=oQUESTIONM)) then
- case token of
- oPACKETLENGTH :
- begin
- ScanForValue(commandLine, commandLen, value,
- SDECIMAL, commandType);
- TestAndSetValue(value, SizeSend, token,
- commandType);
- end;
- oPADDING :
- begin
- ScanForValue(commandLine, commandLen, value,
- DECIMAL, commandType);
- TestAndSetValue(value, Pad, token, commandType);
- end;
- oPADCHAR :
- begin
- ScanForValue(commandLine, commandLen, value,
- OCTAL, commandType);
- TestAndSetValue(value, PadChar, token,
- commandType);
- end;
- oTIMEOUT :
- begin
- ScanForValue(commandLine, commandLen, value,
- DECIMAL, commandType);
- TestAndSetValue(value, TheirTimeOut, token,
- commandType);
- end;
- oENDOFLINE :
- begin
- ScanForValue(commandLine, commandLen, value,
- OCTAL, commandType);
- TestAndSetValue(value, SendEol, token,
- commandType);
- end;
- oQUOTE :
- begin
- ScanForValue(commandLine, commandLen, value,
- CHRACTER, commandType);
- TestAndSetValue(value, SendQuote, token,
- commandType);
- end;
- oQUESTIONM :
- if (commandType = oSETTYPE) then
- PrintSetSendReceiveHelp
- else
- PrintShowSendReceiveHelp;
- end { inner case token of }
- else
- if (commandType = oSETTYPE) then
- PrintMessage(INVALIDSETCOMMAND)
- else
- PrintMessage(INVALIDSHOWCOMMAND);
- end; {of oSEND case}
-
- oRECEIVE :
- begin
- ScanForToken(commandLine, commandLen, token, oRECEIVETYPE);
- { This next line checks if token is oPACKETLENGTH, oPADDING,
- oPADCHAR, oTIMEOUT, oENDOFLINE, oQUOTE, or oQUESTIONM. }
- if ((token>=oPACKETLENGTH) and (token<=oQUESTIONM)) then
- case token of
- oPACKETLENGTH :
- begin
- ScanForValue(commandLine, commandLen, value,
- SDECIMAL, commandType);
- TestAndSetValue(value, SizeRecv, token,
- commandType);
- end;
- oPADDING :
- begin
- ScanForValue(commandLine, commandLen, value,
- DECIMAL, commandType);
- TestAndSetValue(value, MyPad, token, commandType);
- end;
- oPADCHAR :
- begin
- ScanForValue(commandLine, commandLen, value,
- OCTAL, commandType);
- TestAndSetValue(value, MyPadChar, token,
- commandType);
- end;
- oTIMEOUT :
- begin
- ScanForValue(commandLine, commandLen, value,
- DECIMAL, commandType);
- TestAndSetValue(value, MyTimeOut, token,
- commandType);
- end;
- oENDOFLINE :
- begin
- ScanForValue(commandLine, commandLen, value,
- OCTAL, commandType);
- TestAndSetValue(value, MyEol, token,
- commandType);
- end;
- oQUOTE :
- begin
- ScanForValue(commandLine, commandLen, value,
- CHRACTER, commandType);
- TestAndSetValue(value, MyQuote, token,
- commandType);
- end;
- oQUESTIONM :
- if (commandType = oSETTYPE) then
- PrintSetSendReceiveHelp
- else
- PrintShowSendReceiveHelp;
- end { of inner case token of }
- else
- if (commandType = oSETTYPE) then
- PrintMessage(INVALIDSETCOMMAND)
- else
- PrintMessage(INVALIDSHOWCOMMAND);
- end; {of oRECEIVE case}
-
- oTRANSMODE :
- begin
- ScanForToken(commandLine, commandLen, value, oTRANSTYPE);
- TestAndSetValue(value, transtype, token, commandType);
- end;
- oEIGHTQUOTE :
- begin
- ScanForValue(commandLine, commandLen, value,
- EBCHRACTER, commandType);
- TestAndSetValue(value, EBQChar, token, commandType);
- end;
- oDEBUGGING :
- begin
- ScanForToken(commandLine, commandLen, value, oDEBUGTYPE);
- TestAndSetValue(value, debugging, token, commandType);
- end;
- oFILERECORD :
- begin
- ScanForToken(commandLine, commandLen, value, oFILERECTYPE);
- TestAndSetValue(value, fileEOL, token, commandType);
- end;
- oPARITY :
- begin
- ScanForToken(commandLine, commandLen, value, oPARITYTYPE);
- TestAndSetValue(value, parity, token, commandType);
- end;
- oSPEED :
- begin
- ScanForValue(commandLine, commandLen, value,
- IDECIMAL, commandType);
- TestAndSetValue(value, lSpeed, token, commandType);
- end;
- oDELAY :
- begin
- ScanForValue(commandLine, commandLen, value,
- DECIMAL, commandType);
- TestAndSetValue(value, delay, token, commandType);
- end;
- oQUESTIONM :
- if (commandType = oSETTYPE) then
- PrintSetHelp
- else
- PrintShowHelp;
- oALL :
- if (commandType = oSHOWTYPE) then
- PrintAllParameters
- else
- PrintMessage(INVALIDSETCOMMAND);
- end { of outer case token of }
- else
- if (commandType = oSETTYPE) then
- PrintMessage(INVALIDSETCOMMAND)
- else
- PrintMessage(INVALIDSHOWCOMMAND);
- end;
-
-
- { Routine to Parse the incoming line for a valid command. }
-
- procedure ParseInput(var commandLine : string80;
- var commandLen : integer;
- var runType : command);
-
-
- var
- token : integer;
-
- begin
- ScanForToken(commandLine, commandLen, token, oMAINTYPE);
-
- if token in [oSET, oSHOW, oSTATUS, oHELP, oEXIT,
- oQUIT, oSEND, oRECEIVE, oQUESTIONM, oIBEX] then
- case token of
- oSET : ParseSetShowCommand(commandLine, commandLen, oSETTYPE);
- oSHOW : ParseSetShowCommand(commandLine, commandLen, oSHOWTYPE);
- oSEND,
- oRECEIVE :
- begin
- ParseSendReceiveCommand(commandLine, commandLen,
- fileSpec, token);
- if ((token = oSEND) and (sFileSpec = oON)) then
- runType := Transmit
- else
- if (token = oRECEIVE) then
- runType := Receive;
- end;
- oSTATUS : PrintStatus;
- oIBEX : ExecShell(commandLine, commandLen);
- oHELP : PrintHelpCP6(commandLine, commandLen);
- oQUESTIONM : HelpMessage(29);
- oEXIT,
- oQUIT : exitProgram := true;
- end { of case token of }
- else
- PrintMessage(INVALIDCOMMAND);
- end;
-
-
- { Routine to print command line prompt and get user input }
-
- function CommandPrompt(var commandLine : string80;
- var commandLen : integer) : boolean;
-
-
- var
- noInput : boolean;
- j : integer;
-
- begin
- noInput := true;
-
- write(KERMITPROMPT);
- while ((noInput) and (not eof)) do
- begin
- j := 1;
- while (( not eoln ) and ( j<=LARGESIZE )) do
- begin
- read (commandline[j] );
- j := j+1
- end;
- readln;
- commandLen := j-1;
-
- if (commandLen > 0) then
- begin
- noInput := false;
- StrUpcase(commandLine, commandLen);
- SkipBlanks(commandLine, commandLen);
- end
- else
- write(KERMITPROMPT);
- end;
-
- CommandPrompt := not(noInput);
- end;
-
-
- procedure PromptAndParseUser(var exitProgram : boolean;
- var RunType : command);
-
-
- begin
-
- while ( not(exitProgram) and
- not((RunType = Receive) or
- (RunType = Transmit) or
- (RunType = Connect)) ) do
- begin
- if CommandPrompt(commandLine, commandLen) then
- ParseInput(commandLine, commandLen, RunType)
- else
- exitProgram := true;
- end;
-
- { Set parms that could not be set normally }
- if (debugging = oOFF) then
- debug := false
- else
- debug := true;
-
- if (fileEol = oLF) then
- EOLFORFILE := LineFeed
- else
- if (fileEol = oCRLF) then
- EOLFORFILE := CrLf
- else
- EOLFORFILE := JustCr;
-
- if (transtype = oASCII) then
- begin
- EBQstate := Ascii;
- end
- else
- begin
- EBQstate := Binary;
- end;
- if parity <> DEFPARITY then
- begin
- DEFPARITY := parity ;
- case parity of
- oNONE: set_parity (0) ;
- oODD : set_parity (1) ;
- oEVEN: set_parity (2) ;
- end {case}
- end ;
- end;
- begin
-
-
- KermitInit ;
-
- 9999: { Goto for an error packet }
-
- RunType := Invalid;
- exitProgram := false;
-
- while not(exitProgram) do
- begin
-
- PromptAndParseUser(exitProgram, RunType);
-
- if not(exitProgram) then
- begin
- ResetKermitPacketNumber;
- case RunType of
- Receive,
- Transmit : KermitMain ;
- Invalid,
- Connect : {do nothing}
- end;
- end;
- RunType := Invalid;
- end;
-
- set_profile (1, linespeed, width, parity) ; {reset}
-
-
- end.
- !EOD
- !PL6 ME OVER PL6_OBJ (LS)
- SET_PROMPT: PROC ;
- %INCLUDE CP_6;
- %FPT_PROMPT (FPTN = PROMPT, PROMPT = NONE, VFC = YES) ;
- DCL NONE CHAR(1) CONSTANT INIT ('@') ;
- CALL M$PROMPT (PROMPT) ;
- RETURN ;
- END SET_PROMPT ;
- %EOD ;
- SET_PROFILE: PROC (MODE, SPEED, WIDTH, PARITY) ;
- %INCLUDE CP_6 ;
- %FPT_TRMATTR (FPTN = ATTRIBUTES, TRMATTR = VLP_TRMATTR) ;
- %VLP_TRMATTR ;
- %FPT_PLATEN (FPTN = PLATEN, PLATEN = VLP_PLATEN) ;
- %VLP_PLATEN (WIDTH=100) ;
- %F$DCB ;
- DCL MODE UBIN WORD ;
- DCL SPEED UBIN WORD ;
- DCL WIDTH UBIN WORD ;
- DCL PARITY UBIN WORD ;
- IF MODE = 0 THEN
- DO ;
- CALL M$GTRMATTR (ATTRIBUTES) ;
- SPEED = VLP_TRMATTR.SPEED# ;
- WIDTH = VLP_TRMATTR.WIDTH# ;
- PARITY = VLP_TRMATTR.PARITY# ;
- VLP_TRMATTR.WIDTH# = 100 ;
- CALL M$STRMATTR (ATTRIBUTES) ;
- VLP_TRMATTR.WIDTH# = WIDTH ;
- WIDTH = DCBADDR (DCBNUM (M$UC)) -> F$DCB.WIDTH# ;
- CALL M$PLATEN (PLATEN) ;
- VLP_PLATEN.WIDTH# = WIDTH ;
- END ;
- ELSE
- DO ;
- CALL M$STRMATTR (ATTRIBUTES) ;
- CALL M$PLATEN (PLATEN) ;
- END ;
- RETURN ;
- END ;
- %EOD ;
- GETLINEINPUT: PROC(INCOMING,LENGTH,BEPATIENT,RESULT);
- %INCLUDE CP_6;
- %FPT_READ (FPTN = READ_COMM_LINE,
- DCB=F$LINE,
- TRANS=YES );
- %FPT_TRMCTL (FPTN = SET_TERM,
- TRMCTL=TERM);
- %VLP_TRMCTL (FPTN = TERM,
- ACTONTRN=YES);
- %FPT_TRMPRG (FPTN=TYPEAHEAD,DCB=M$UC,PURGEINPUT=YES);
- %FPT_EOM (FPTN = TIMEOUT,
- EOMTABLE=VLP_EOMTABLE,
- TIMEOUT=0,
- UTYPE=SEC );
- %VLP_EOMTABLE(FPTN = VLP_EOMTABLE,
- VALUES=STD);
- DCL F$LINE DCB ;
- DCL INCOMING CHAR(LENGTH);
- DCL LENGTH UBIN WORD;
- DCL BEPATIENT UBIN WORD;
- DCL RESULT SBIN WORD ALIGNED;
-
- TIMEOUT.V.TIMEOUT# = BEPATIENT ;
- CALL M$EOM( TIMEOUT );
- READ_COMM_LINE.BUF_ = VECTOR (INCOMING);
- RESULT = 1;
- CALL M$STRMCTL (SET_TERM);
- /* CALL M$TRMPRG (TYPEAHEAD); */
- CALL M$READ( READ_COMM_LINE ) ALTRET( TIMED_OUT );
- RESULT = 0;
-
- TIMED_OUT:
- TIMEOUT.V.TIMEOUT# = 0;
- CALL M$EOM( TIMEOUT );
- RETURN;
-
- END GETLINEINPUT;
- %EOD ;
- TAKE_NAP: PROC (TIME) ;
- %INCLUDE CP_6;
- %FPT_WAIT (FPTN = WAIT, UNITS = 25);
- DCL TIME UBIN WORD ;
- WAIT.V.UNITS# = TIME ;
- CALL M$WAIT (WAIT) ;
- RETURN ;
- END TAKE_NAP ;
- %EOD ;
- SET_PARITY: PROC (MODE) ;
- %INCLUDE CP_6 ;
- %FPT_TRMATTR (FPTN = PARITY, TRMATTR = VLP_TRMATTR) ;
- %VLP_TRMATTR ;
- DCL MODE UBIN WORD ;
- VLP_TRMATTR.PARITY# = MODE ;
- CALL M$STRMATTR (PARITY) ;
- RETURN ;
- END ;
- !EOD
- !LINK KERMIT_OBJ, PL6_OBJ OVER KERMIT_RU
-